MS Access for Mac

May 14, 2008

office 2008

The new version of Office 2008 is out now for Mac and we will look at why this version, like all the others that have come before does not include MS Access.

Current programs can simply be ported between operating systems as they are written in high level descriptive programming languages, some of which are virtually identical on every platform. While with the cross-platform Java language you can simply recompile the project for any operating system. Although with java you will have to face certain limitations in how you code your program. With most other languages all the code that communicates directly with the OS will have to rewritten as they are different for every platform. Also some libraries are platform specific so you have to find alternate methods which make work in a different manner as well, unless you are willing to program them. While the code that actually does the processing within your program can simply be imported directly into the new version with little or no re-coding as long as the programming language remains the same.

Unfortunately in the case of access it doesn’t just communicate with the system it also uses many other libraries and applications like .Net and Microsoft Jet Database Engine which are only available on Windows. So you would have to port all of these libraries and applications onto Mac as well, for Access to work.

Microsoft has never shown much interest in porting the two biggest components, .Net and Jet to Mac because it’s not in their own interest to do so. Adding the additional architecture of .Net to Mac would make it easier for PC programmers to bring more software to Mac and help raise the quantity of software available for Macs which could not only damage their market share but would offer little financial compensation. As for MSSQL there are many alternatives for Mac some are free open source distributions so you would have a hard time selling it as a product.

All in all, it makes MS Access too large and expensive a project for something that less than half of all Microsoft Office users even use.

Trolltech and KDE Cooperate on Cross-Platform Multimedia Programming Framework

December 13, 2007

OSLO, Norway & TUEBINGEN, Germany–(BUSINESS WIRE)–Trolltech®, the leading cross-platform software development company, and KDE e.V. today announced a technical collaboration on the development of Phonon, a cross-platform multimedia framework that makes it simple for programmers of all experience levels to incorporate multimedia functionality into their applications.

Phonon was initially developed by the KDE community and will be part of the upcoming KDE 4.0 release. Trolltech has now extended Phonon so it can be used on all major desktop operating systems, including Windows® and Mac® OS X. Additionally, Trolltech is contributing its code into the KDE source code repository and has licensed it under the LGPL.

Phonon makes it easier than ever before to include multimedia playback in C++ applications, and most operations can now be accomplished with very little code. The original code for Phonon included a single, Xine-based backend that worked only on UNIX and Linux platforms. Trolltech has created additional backend implementations for GStreamer on Linux, plus backends for Windows and Mac OS X.

Trolltech will incorporate Phonon into the company’s upcoming Qt® 4.4 release, currently scheduled to be released at the end of Q1 2008.

By developing Phonon components within the globally accessible public KDE source repository, Phonon developers are able to watch and participate in the development of Trolltech’s Phonon back-end code and library code contributions. This also allows the community to evaluate and provide input into the work being done by Trolltech’s internal development team. KDE, in turn, benefits by having Trolltech’s employed developers contribute to the ongoing development and maintenance of Phonon, freeing KDE developers to work on other aspects of the desktop. . This is a marked change from how open source libraries are usually integrated into commercial products, which has typically involved pulling snapshots of the open source code into the commercial product. Additionally, the Windows and Mac OS X backends will enable KDE4 applications running on these platforms to include multimedia functionality.

About KDE

KDE is an international technology team that creates integrated Free/Open Source Software for desktop and portable computing. Among KDE’s products are a modern desktop system for Linux and UNIX platforms, comprehensive office productivity and groupware suites and hundreds of software titles in many categories including Internet and web applications, multimedia, entertainment, educational, graphics and software development. Building on the cross-platform capabilities of Trolltech®’s Qt®, KDE4’s full-featured applications run natively on Linux, BSD, Solaris, Windows and Mac OS X.

About Trolltech

Trolltech® creates cross-platform application development frameworks for desktop and mobile device innovation. Trolltech’s software increases the appeal of our customer’s desktop applications and devices while reducing their risks and software development costs. Trolltech’s technologies accelerate the evolution of software by unleashing the creative power of the developer.

Trolltech software is the foundation for thousands of leading products worldwide, many from Global 2000 companies. Trolltech is a second-generation open source company, with a dual licensing business model that supports open source values and methodology in a profitable, sustainable business. The company is listed on the Oslo Stock Exchange under the ticker symbol TROLL. For more information about Trolltech, please visit http://www.trolltech.com.

Trolltech, Qt and Qtopia are registered trademarks of Trolltech ASA. All other trademarks are registered trademarks of their respective owners

Adding a referer specific redirect to your .htaccess file

September 28, 2007

Have you ever had one of those days when you receive so much traffic from a particular site that you need to redirect that traffic to a cached copy of your content? If you can gain access to your .htaccess file than you can implement this very quick bit of code

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_REFERER} (example.com) [NC]
RewriteRule myarticle.html http://www.cacheserver.com/myarticle.html  [R,L,NC]
</IfModule>

The above short code snippet will allow you to send all traffic that comes from example.com looking for myarticle.html to the alternate location of cacheserver.com/myarticle.html. This little bit of code can come in very handy when a particular social media site is sending a ton of traffic to your MySQL/PHP site causing it to crash.

You do not even need to send it to another server. If you simply create a static page on your existing server (I like to use a cache directory) you can send the traffic there. In all honesty it is far better to serve the cached copy from your own server than to send it elsewhere.

1100 Reasons programing is better than having a girlfriend

May 28, 2007

You need to be a programmer to understand these:

0001. No matter how many times you call an “X” no one gets jealous.
0010. Using the same line over and over again always works!
0011. Accurate comments make everyone happy.
0100. If something is not working correctly you can always change the source code.
0101. Programs don’t get offended if you let your friends play with them.
0110. When you write a useful function you can add it to all of your programs.
0111. You can write a program to take input from multiple sources without complaining.
1000. You can not run a program for years and it is always ready when you want it.
1001. You can play with more than one program at the same time.
1010. Programs don’t complain when you use “helper” programs.
1011. Programs exist to serve YOU.
1100. No one goes to jail when they kill a program.

Yes, I’m numbering these in binary.

That is my short list, I hope you like them and feel free to add your own in the comments.

The IT password story

February 9, 2007

This story was told to me by a friend I met while serving in the US Army. His name is Stephen Shields and I have no idea where he is now but if he reads this he should contact me.

To give some background on the story I will tell you the following. Steve worked in an IT shop during the mid 1980’s. In this shop he maintained some networks (Unix environment) and, among his colleagues, he was much smart.

I can’t recall if he was working on a university or at IBM, it was over 15 years ago when he told me this story…

At the IT shop where I worked there were a few good techs and one smart one, me. Back in the mid 80’s I was just one worker, among many, who kept the campus mainframe operational.

We ran Unix, like everyone else did, and though my associates at work could handle most of the day-to-day operations of maintaining a mainframe they were not the brightest folks in regards to programming or how Unix worked.

There were a few joke items scattered about the office such as the proverbial “bit bucket” or “metric” rather than standard crescent wrench but, for the most part, it was a fairly serious shop.

One day a few of my associates approached me to ask me a question. It seems they had found the directory and files where all of the passwords were stored along with the usernames. Please understand, this is back in the day when hashing passwords and network security was almost non-existent.

The only network links off campus were in the 300 baud range. It was easier (and faster) to just dump a tape and fly somewhere than attempt to use a link.

Since only admins had root access and all the techs were admins I knew it was only a matter of time until this question surfaced.

“Hey Steve, we were looking at the password file and we noticed something strange.”
“Yeah, what?”
“Well, everyone on campus has a password but you.”
“I have a password, you just can’t see it because I’m a super user.”
“What? How come you get to be a super user?”

It was all I could do to keep from cracking up at this point. I wasn’t a super user, I had the same access rights as they people did, but I had a secret…

“Well, if you guys were smart and knew enough about computers maybe you could be super users too!”

They left in a bit of a huff, mumbling to each other how unfair it was that I had special perks that they did not.

The next day my boss pulled me aside, he wanted to know what all the trouble was about and why the other techs were acting uppity. Once again, I had to keep a straight face. I walked with him back to his office, made sure no one was around, closed the door and talked to him.

I brought up the password file and showed him what all the fuss was about. When he saw that I was the only one without a password he grinned. He knew what was going on.

“You bastard!”
“Yup, that’s me.”
“You got them all worked up over this?”
“Yep.”
“Get out of here before I smack you around for being a wise-ass!”

See, the thing that my co-workers never caught on to but my boss saw right away was that the file was ASCII with no encryption or anything. If those passwords had been hashed or displayed in HEX or anything other than ASCII than my coworkers would have never been mislead. What I did was exploit the weakness in the system to make everyone think my password was so secure that no one could see it.

How did I do it? Simple, my password was eight characters long. Eight taps of the spacebar to be precise!

Multi-Dimensional Arrays

December 17, 2006

A common tool many programmers use is the array.

The array is very useful in storing like data. Arrays can also be sorted and searched.

What many programmers do not do is use an array along more than two axis.

The simplest form of an array is one with only one axis. It is nothing more than a long row of data.

int array[50];

Let’s imagine now that we work in a large warehouse and our boss has tasked us with writing a simple program to inventory all of the items in the warehouse and where they are in the building.

In it’s most basic sense, a one axis array is equivalent to a long line of boxes on the floor. This might work in a small warehouse but our building is quite large. We will look next at the two axis array, which is also the most common.

int array[50][50];

Now we have a two axis array. We can consider the first axis to be the row and the second axis to be the column.

We have gotten rid of the long snaking line along the floor and replaced it with a system of rows and columns to find where everything is but, everything is still on the floor!

The boss says he wants some shelving units in each row of the warehouse, but how do we account for this?

int array[50][50][10];

We have just moved on to the three axis array. Since we are already using the first two axis for row and column we will now use the third axis for shelf.

I’m only using ten shelves in the warehouse so I capped out that axis of the array at ten.

Now, if the boss wants to know where the rope is we can tell him it’s in row 11, column 21 and shelf 3.

What’s that? How do we store “rope” in an integer array? Well, we use product numbers to represent what an item is. The array does not store “rope” at array[11][21][3] but instead it holds the product ID code 7259 which means “rope.”

“Well, that’s all well and good,” says the boss, “but, sometimes we sell out of something and put something new in the warehouse. I don’t want to lose the fact that the shelf once held rope on it, how can we track that?”

Now we use a four dimensional array.

int array[50][50][10][50];

We now have an array that tracks: row, column, shelf and time. Our fourth dimension is one of time, it can be used to tell us what was once on that shelf.

Now, when the boss says, “Where’s the rope,” we can respond, “row 11, column 21 and shelf 3 (time=0)!”

If he then asks us what used to be there we can go back through the time element of the array and know what was once there.

You might be wondering why it is important to track what was once on a shelf? If you have ever worked in a warehouse you probably know that sometimes things get lost or someone misplaces something. If a report comes down that says we have one rope left, and we know where the rope used to be, there is a good chance we can go to where the rope used to be and find one near by.

If it helps think of arrays in the following way:

One element = straight line
Two elements = rectangle
Three elements = box
Four elements = a series of boxes in a straight line

You can go beyond four elements when creating arrays but you will likely not need to. In fact, if you were tracking the contents of a warehouse you would probably have a large array of pointers that point at objects which contain the information about the item in the warehouse.

You will likely never have a need to use anything bigger than a two dimensional array but I hope that this short exercise has enabled you to properly wrap your mind an array with more than two axis.

Re-usable Code: Linked Lists

October 28, 2006

One of the most useful ways to store data is the linked list.

Read on and explore a very basic framework that you can use to easily add them to your program.

We begin with the h file. Please note, this code is written with wxwidgets in mind but the only change required to use this code elsewhere will be the changing of the variable “wxString” to something else.

Because this is only a sample code snippet for training purposes, the two variables “Name and Value” will not carry over to your own program.

/////////////////////////////////////////////////////////////////////////////
// Name:        hmtkdataitem.h
// Purpose:     hmtk data item function
// Author:      Stephen De Chellis
// Modified by:
// Created:     04/09/05
// Copyright:   (c) Stephen De Chellis
// License:     Creative Commons Attribution-ShareAlike 2.5 License
/////////////////////////////////////////////////////////////////////////////

#ifndef __HMTKDATAITEM_H__
#define __HMTKDATAITEM_H__

class HMTKDataItem
{
    public:
        static HMTKDataItem* pHead;
               HMTKDataItem* pNext;
               wxString      Name;
               int           Value;

        HMTKDataItem();
        ~HMTKDataItem();

        void          AddHead(HMTKDataItem* DI);
        void          AddTail(HMTKDataItem* DI);
        int           Remove (HMTKDataItem* DI);
        void          Clear  (void);
        HMTKDataItem* Find   (wxString Search);

};

#endif

Now let us look at the cpp file

/////////////////////////////////////////////////////////////////////////////
// Name:        hmtkdataitem.cpp
// Purpose:     hmtk data item function
// Author:      Stephen De Chellis
// Modified by:
// Created:     04/09/05
// Copyright:   (c) Stephen De Chellis
// License:     Creative Commons Attribution-ShareAlike 2.5 License
/////////////////////////////////////////////////////////////////////////////

#include “precomp.h”
#include <fstream>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include “hmtkdataitem.h”

HMTKDataItem* HMTKDataItem::pHead = 0;
using namespace std;

HMTKDataItem::HMTKDataItem()
{
    Name.Clear();
    Value=0;
    pNext=0;
}
HMTKDataItem::~HMTKDataItem()
{
}

void HMTKDataItem::AddHead(HMTKDataItem* DI)
{
    DI->pNext = pHead;
    pHead = DI;
}

void HMTKDataItem::AddTail(HMTKDataItem* DI)
{
    cout << “Adding Tail” << endl;
    DI->pNext = (HMTKDataItem*)0;
    if (pHead == 0)
    {
        pHead = DI;
        return;
    }
    HMTKDataItem* pCurrent = pHead;
    cout << “Entering while loop” << endl;
    while(pCurrent->pNext)
    {
        pCurrent = pCurrent->pNext;
    }
    cout << “Leaving while loop” << endl;
    pCurrent->pNext = DI;

    cout << “Leaving Adding Tail” << endl;
    return;
}
int HMTKDataItem::Remove(HMTKDataItem* DI)
{
    HMTKDataItem* pCurrent = pHead;
    if(pCurrent == (HMTKDataItem*)0)
    {
        return 0;
    }
    if(DI == pHead && DI->pNext!=0)
    {
        pHead = DI->pNext;
        delete DI;
        return 0;
    }
    if(DI == pHead && DI->pNext==0)
    {
        pHead = 0;
        return 0;
    }
    while(pCurrent)
    {
        if(DI == pCurrent->pNext)
        {
            pCurrent->pNext = DI->pNext;
            DI->pNext = (HMTKDataItem*)0;
            delete DI;
            return 1;
        }
        pCurrent = pCurrent->pNext;
    }
    return 0;
}
void HMTKDataItem::Clear(void)
{
    HMTKDataItem* pPrevious;
    if (pHead == 0)
    {
        return;
    }
    HMTKDataItem* pCurrent = pHead;
    while(pCurrent->pNext)
    {
        pPrevious = pCurrent;
        pCurrent = pCurrent->pNext;
        delete pPrevious;
    }
    pHead=0;
    return;
}
HMTKDataItem* HMTKDataItem::Find(wxString Search)
{
    if (pHead == 0)
    {
        return 0;
    }
    HMTKDataItem* pCurrent = pHead;
    while(pCurrent->pNext)
    {
        if(pCurrent->Name.Contains(Search)==1)
        {
            return pCurrent;
        }
        pCurrent = pCurrent->pNext;
    }
    return 0;
}

Yep, that’s a lot of code!

Once again, please note that the variable “Name” is used in the Find function so if you change it, you also need to change the Find function

In the following example we will add an item to the linked list

HMTKDataItem* DI = new HMTKDataItem;  // create a pointer to a new item
DI->Name = Selection;                 // Give Name a value
DI->Value = 1;                        // give Value a new value
HMTKDataItem.AddTail(DI);             // Add the new item to the tail
delete DI;                            // delete the pointer

Now, before adding an item it might not be a bad idea to search the linked list to see if it already exists.

HMTKDataItem* DI = new HMTKDataItem;   // Create a pointer
DI = HMTKDataItem.Find(Selection);     // Search the existing linked list
if(DI == 0)
// Now you know it does not exist

To remove an item you would use:

HMTKDataItem* DI = new HMTKDataItem;  // create a pointer
DI = HMTKDataItem.Find(Selection);    // use find
if(DI != 0)                           // as long as DI gets something to point at
{
    HMTKDataItem.Remove(DI);          // we now delete the item in the linked list
}

That is about it. I’ve given you a very brief overview on how to use a linked list in your program. If you have any questions please leave a comment.

A simple program to search large text files

September 27, 2006

A few years ago I took over webmaster duties for a very active community forum. About a month into the job the unthinkable happened, we lost the table that contained all of the posts!

I had backups (7 day rolling system) but the backups were a good 24 hours old and the server kept dropping lines while it was chugging away at restoring the database table.

I needed to go into the sql file and pull out all of the lines for the post table but I had one very large problem; The sql file was 524MB and my computer only had 128MB of RAM!

I tried to cajole my computer into opening the file but it was simply too big. Rather then curse my poor under-powered computer I got an idea.

Since I knew the structure of the sql commands I could write a program to open the file, line-by-line, and take the lines I needed and put them in a new file.

Now, it is important to note that I was unaware of the program Grep at the time. If I had known of Grep back then I would have just used that…

So, using some very simple C programming language functions I built a program that would search any text file for a given search string and output it all to a new file. Even though the post table itself was still huge, the shear number of sub-forums allowed me to break it down into files for each sub-forum.

Now I had about 124 sql files, one for each area of the forums. It was a simple process to load each one up onto the server and load the table data back into the mySQL server. Then I had only to a do a quick check of the number of items in the table compared to the number of lines in the file to be sure all the statements were executed.

I give the following code to you to use, modify, etc… I ask only that you follow my Creative Commons Attribution-ShareAlike 2.5 License.

It would be a very easy modification to change this program to search an entire directory of text files for a given string. I imagine some of those “spy on your kids” program do just that…

Please note that this was thrown together in about 5 minutes and is not optimized nor does it have any safegaurds written into it.

#include <fstream>
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
const int MAX_LEN = 102400 ;
int main(int argc, char *argv[])
{
    int i = 0;
    if(argc!=3)
    {
        // give info on how to run program
        // Creative Commons Attribution-ShareAlike 2.5 License
        printf("sqlquery copyright 2005 Stephen De Chellis \n");
        printf("sqlquery takes 2 arguments\n\n");
        printf("sqlquery [filename] [search string]\n\n");
        printf("[filename]      = name of file to open for searching\n");
        printf("[search string] = string to search the file for\n\n");
        printf("sqlquery will search the file line by line and store the results\n");
        printf("in a new file named [search string].sql\n");
        return 0;
    }
    char line[MAX_LEN];
    char filename[256];
    char filename2[256];
    i = 0;
    strcpy(filename2,argv[2]);
    strcat(filename2,".sql");
    strcpy(filename,argv[1]);    

    ifstream infile;
    ofstream outfile;
    infile.open (filename, ifstream::in);
    if(!infile)
    {
        printf("unable to find file: %s",filename);
        return 0;
    }
    outfile.open (filename2, ofstream::out);
    if(!outfile)
    {
        printf("unable to create file: %s",filename2);
        return 0;
    }
    printf("\n working");
    do
    {
        infile.getline(line,MAX_LEN);

        if(strstr(line,argv[2])!=NULL)
        {
            outfile << line << endl;
            i++;
            printf(".");
            strcpy(line,"");
        }
    }while(infile.eof()==0);
    printf("Found %i matches",i);
    infile.close();
    outfile.close();
    return i;
}

Re-usable Code: Populating Listboxes in Windows

September 11, 2006

One thing most programmers who program for windows will have to deal with is the Listbox.

The Listbox is a very useful item in the programmers arsenal. It’s cousin, the ComboBox is a close second. You can use a Listbox to display a list of items to a user and allow them to select and item (or multiple items) and then do something with those items.

I’m not going to get too detailed into the how’s and why’s of Listboxes but will instead show you some very simple re-usable code that I release to you under a Creative Commons Attribution-ShareAlike 2.5 License . All I ask is that you do not claim the code as your own and give me proper credit for it. If you have some good ideas on improving this small code snippet then you can leave a comment below and I will update the article to show your changes.

I first wrote this snippet back in 2002 and it was written while coding for Windows 98 machines.

The first thing every bit of code needs is a header file:

/*—————————————————-
    Basic Listbox Code (re-usable)
    (c) Stephen De Chellis 2002
    Creative Commons Attribution-ShareAlike 2.5 License
    Listbox.h - header file for Listbox.cpp
  —————————————————-*/

#ifndef LISTBOX_H
#define LISTBOX_H

struct BigBuffer{
    char Buffer[256];
};

/* Prototypes for Listbox.c */
extern int FillListBox (HWND hwnd, int ID, struct BigBuffer buffer[], int s);
/* end of Listbox.h */

#endif

Now that we have the header file we can go forward with the cpp file. Before I go ahead, please note the pre-proccesor statements I put in the listbox.h file. They are very important as once your program gets large enough you may inadvertantly include the same header file twice. The if statement, followed by declaring the constant insures that an include file will not be added twice. That’s a headache you want to avoid!

Now let us look at the contents of listbox.cpp

/*—————————————————-
    Basic Listbox Code (re-usable)
    (c) Stephen De Chellis 2002
    Creative Commons Attribution-ShareAlike 2.5  License
    Listbox.cpp - Contains code for filling a Listbox
  —————————————————-*/

#include <windows.h>
#include “Listbox.h”

int FillListBox (HWND hwnd, int ID, struct BigBuffer buffer[], int s)
{
   /********************************************************************
      hwnd         - handle to window with the listbox
      ID           - ID number of listbox to be filled with data
      buffer[]     - String Array that will be written to listbox
      s            - how many elements of string array to write
      This function fills listboxes and then returns an int denoting
      the quantity of items listed.
   *********************************************************************/
   int i=0;
   SendDlgItemMessage (hwnd, ID, LB_RESETCONTENT, 0,0);
   do
   {
      SendDlgItemMessage(hwnd, ID, LB_ADDSTRING, i, (LPARAM)  buffer[i].Buffer);
      i++;
   } while(i<s);
   return i;
}

I do appologize for some of the formating issues on this blog. I try to get things to look as I like them and then the backend throws in a ton of code that I do not want…

The core of the above function is to take a structure and fill it with a series of strings. You then send the structure and an integer telling the function how many items (in that structure) you want to have sent to the Listbox. The function then returns i, which should be equal to the number of items sent. If it does not return the same number as the number of items sent then you know an error has occured and you can write some code to fix it.

I have since re-written this code for wxWidgets and included much better error handling.

The above code is very simple and you will probably not use it as is unless you are new to programming.

The first line in the FillListBox function is a call to SendDlgItemMessage (hwnd, ID, LB_RESETCONTENT, 0,0). This line simply tells the program to clear all of the contents out of the Listbox (ID) in question. If you do not clear the contents first when the program executes the next block of code you will find yourself adding entries to the entries already there. You do not always clear a listbox before sending items to it, but in this basic example we are clearing it and fully re-populating each time.

The following loop then adds strings to the Listbox, one-by-one, until it has added as many items as it was told to add. when the loop ends this function returns the number of items added.

This is only the first in a series of programming articles. If there are any requests for further help in dealing with Listboxes please comment below.

I used the services of Code Colorizer to colorize the above code snippets.