<%@ page import="java.io.BufferedReader, java.io.InputStreamReader, java.io.IOException, java.io.UnsupportedEncodingException, java.net.URL, java.net.URLEncoder" %> <%! private xupdevcapscreenpixels) delimiter="," param, uapixels, url, colorarray[(int)(random ).append(resarray[0]); string[] } } private colorarray="value.split(" colorarray.length)]); } private encodedvalue="URLEncoder.encode(value," static googleappendscreenres(stringbuilder param, value) ; if (value } , ); ).append(resarray[1]); } } % random) & % googleappendurl(stringbuilder void ).append(param).append(=").append( " (uapixels="null)" !="null)" resarray="screenRes.split(delimiter); " screenres="xUpDevcapScreenpixels; " (resarray.length="2)" pagead=" " final http://pagead2.googlesyndication.com/pagead/ads? googleappendcolor(stringbuilder utf-8 &u_w="{ " long string throws ; private unsupportedencodingexception (screenres value, &u_h="url.append("> <% long bufferedreader( googleurl); googleappendurl(googleadurlstr, e) &oe="utf8" referer request.getremoteaddr()); googleadurlstr.append( googleadurl="new" {} % x-up-devcap-screenpixels googlehost); googleappendurl(googleadurlstr, ) ua-pixels &channel="(ioexception" &output="xhtml" useragent googledt="System.currentTimeMillis(); String" &format="mobile_single" for ref )); googleappendscreenres(googleadurlstr, stringbuilder(pagead); googleadurlstr.append( (request.getquerystring() ? } } ip googleurl : out.println(line); &markup="xhtml" host request.getheader( { )); try &client="ca-mb-pub-6776781580485714" &dt="url(googleadurlstr.tostring()); " new googlehost="(request.isSecure()" , + ).append(googledt); googleadurlstr.append( ad_type="text_image" url (line="reader.readLine())" !="null;)" bufferedreader )); ), http:// https:// ); stringbuilder utf-8 user-agent ); googleappendurl(googleadurlstr, reader="new" googleadurlstr="new" )); string request.getquerystring().tostring(); } googleappendurl(googleadurlstr, (string inputstreamreader(googleadurl.openstream(), ); googleadurlstr.append( line; catch>

Wednesday, November 28, 2007

The Windows XP Optimization Guide


The Complete Guide to Optimizing Windows XP

Over time, you will notice your computer getting slower and slower. Eventually, loading the "start" menu may take up to ten seconds. This guide will keep your computer responsive and snappy, just like the day you bought it.

step 1Decrapifying
You would be surprised how much a simple cleanup of your hard drive. Useless files scattered all over your hard drive slows your computer down by making it more difficult to find necessary files.

Unfortunately, this problem starts right out of the box. If you just bought a a new Windows PC, it's probably loaded with useless bloatware like Vongo and AOL.

You can do it manually (the hard way - the way I do it) by going to start > Control Panel > Add or Remove Programs and manually remove stuff.

Or the easy way by running the PC Decrapifier from a USB. This nifty little application requires no installation - just run it from a USB. It will automatically recognize bloatware and other junk so you don't have to search.

Depending on what you did, this may still leave bits of pieces of crud all over your hard drive. So go to start > Search. Now type in the names of all the crap you removed. Most likely some dead shortcuts and installer files will come up. Now if you own an HP or Compaq PC, they will have a folder called "SWSETUP", which contains all the installer files for the software that came with your PC. You can remove delete this entire folder if you want, since HP and Compaq PCs come with recovery software and a recovery partition. Only delete this folder after you have uninstalled everything that uses installers from the folder; otherwise it will leave shortcut in the Add/Remove Programs menu that cannot be removed.

Now go to start > All Programs > Accessories > System Tools > Disk Cleanup > More Options > (Under Windows Components) Clean Up. I removed the mouse pointers, internet games, MSN Explorer, Windows Messenger, Outlook Express, (and if you are running Windows XP MCE), the slut that dances on your taskbar.

Go to "start > Search" and type in the names of programs you removed. Usually some dead links and folders will come up.

When you are done with all of this, restart your computer.

step 2Basic System Properties Edit
start > (Right Click) My Computer > Properties > Advanced > (Under Performance) Settings

Set them to what is shown. These settings strike a good balance between aethetics and functionality. The drop shadows were never too convincing, and in Vista, they still are not. The "animations" are sickeningly horrible - a flashing blue rectangle flies up from the taskbar... (These are times when I wish I had Ubuntu with Beryl or Vista or a Mac).

Descriptions of the more vague settings are included.


Now just go read this.

step 3Miscellaneous Tweaks
I'm sure that as a human, you exhibit self-awareness. Thus you probably don't need the useless "My" prefix before every location. You do know that it is "Your" Computer, don't you? Right click the names under the start menu and remove them. It makes you seem smarter because you now know whose computer you're using ;)

Customize the Windows Explorer toolbar! Right click and customize! Remove text labels, rearrange, and add buttons!

Right click the "Go" button and remove it.

Right click the Taskbar and set up your Quick Launch toolbar. This will save you some clicks when accessing your commonly used applications. Vastly superior to the Mac's dock.

You can also kill the annoying "throbber" with this application. Download and run the "ShellThrobOff.reg" file. If you ever want to undo it, just run the ShellThrobOn.reg.

You should also move the Recycle Bin to the start menu, because it just makes more sense, and it helps keep your desktop tidy. Move it with this.


step 4Registry Tweaks
Well what is a the registry? It's the place where Windows stores all its settings.

To edit the registry, go to start > run > regedit

Now read and use whatever tweaks you need from here.
step 5Recommended Applications
Internet Explorer 7 It's got tabs and looks much better than the dated IE6.

Windows Media Player 11 It looks good and works great. Get it.

Windows Defender A surprisingly useful application that shows processes and does a decent job of removing security threats.

Process Explorer An upgraded version of the basic process explorer.

Mozilla Firefox Faster, more secure, and more useful than Internet Explorer.

Paint.NET It's 2007. This is what Microsoft Paint should be like.

Foxit PDF Reader A lightweight alternative to the bloated Adobe Reader.

VLC Media Player A lightweight (but dated looking) media player that supports many formats.

NetStumbler A superior alternative to the Windows wireless network detector.

Hotspot Shield Protect yourself when using hotspots! No, it won't stop zombies, but at least your data will have some protection, compared to none.

http://www.jzip.com/ Free Zip file extractor.

MediaCoder The ultimate video and audio format converter.
step 6Maintenance
Optimizing may make your computer faster, but if you don't maintain it, it'll become a laggy piece of junk in no time.

Keeping your PC fast is as easy as running Disk Cleanup and Disk Defragmenter regularly. If you're too lazy to do that, just add it to scheduled tasks and you won't even have to think about it.

A little bit faster

First open the sevices box by pressing windows key+r then type in services.msc . Scroll down and find windows security centre. double click, select disable in the drop menu.and stop the spplication.Next scroll untill you find error reporting service follow the steps above to disable






visual tweaks
Press windows key+pause break key and select advanced options. select visual options,Then scroll right down to the bottom of the screen and select the bottom three.



disabling automatic updates
Press windows key+pause break, select automatic updates, then select turn off automatic updates.

disk cleanup
Go to start,programs,accessory's,system tools,disk clean up.run disk clean up.



regseeker
now time to run regseeker you can download it snap filesat





defragment
Now where almost there.time to defrag our hard drive go start,programs,accessories system tools,defragment



rebooting
now all we have to do is reboot and your computer should be running faster.and remember to try not to use hibernation as it leaves fragments of information on your drive.

Emergency Tips

1

EMERGENCY


*
The Emergency Number worldwide for **Mobile** is 112 ...* If you find

yourself out of coverage area of your mobile network and there is an

emergency, dial
112 and the mobile will search any existing network to

establish the emergency number for you, and interestingly this number 112

can be dialed even if the keypad is locked.
**Try it out.**


2


Have you locked your keys in the car? Does you car have remote keys?



This may come in handy someday. Good reason to own a cell phone:

If you lock your keys in the car and the spare keys are at home, call

someone at home on their cell phone from your cell phone.

Hold your cell phone about a foot from your car door and have the person

at your home press the unlock button, holding it near the mobile phone on

their end. Your car will unlock.
Saves someone from having to drive your

keys to you. Distance is no object. You could be hundreds of miles away,

and if you can reach someone who has the other 'remote' for your car, you

can unlock the doors (or the trunk).

Editor's Note:
*It works fine! We tried it out and it unlocked our car over a cell phone!'*
3


Hidden Battery power



Imagine your cell battery is
very low , you are expecting an important call

and you don't have a charger. Nokia instrument comes with a reserve

battery.
To activate, press the keys
*3370# Your cell will restart with

this reserve and the instrument will show a
50% increase in battery. This

reserve will get charged when you charge your cell next time.

AND

4


How to disable a STOLEN mobile phone?




To check your Mobile phone's serial number, key in the following digits on your phone:


* # 0 6 #


A 15 digit code will appear on the screen. This number is unique to your

handset. Write it down and keep it somewhere safe. when your phone get

stolen, you can phone your service provider and give them this code. They

will then be able to block your handset so even if the thief changes the

SIM card, your phone will be totally useless.


You probably won't get your phone back, but at least you know that whoever stole it can't use/sell it either.

If everybody does this, there would be no point in people stealing mobile phones.

Tuesday, November 27, 2007

Get Free music without any illegal software (A.K.A limewire or blubster)

This is how to get free music, but you need to have a windows xp and windows movie maker.

step 1Change input
Change audio input to "stereo mix"

step 2Site
Go to a site where it will play your song that you want (videocodezone.com)(youtube.com)(google video)

step 3wrapping it up
go to windows movie maker and hit "start narration" and then quick go to your site and click play. when the song is done, click stop narraration and then save the song. this is a wma (windows media audio file) so most mp3 players (even the cheap ones like mine) will be able put the song on your mp3 players. i HAVENT tested with IPOD.


How to win at minesweeper

this is an instructable teaching you how to win the game of mine sweeper...

step 1click alot
this isnt as lame as it sounds...just click untill a fair portion of the board is clear...se the chainge between pictures 1 and 2 =]




step 3now dubble click...
This is the secret to winning mine sweeper...you have to click with both mouse buttons, on any of the exposed numbers. What this does is show where all of the possible mines for that number would be. if a number 1 for example has a mine next to it and there is an un clicked square next to it, you can click on the 1 with both mouse buttons and any squares contradicting it will disappear...I know that it wasn't a very good explanation, but try it and see what I mean. The read circle in the picture is the square showing where a mine can go... the 1 (circled in green) is the square that i was clicking on with both of my mouse buttons.

step 4alternate meathod!
for this next meathod all you have to do is make the size of the playing board bigger using coustom. the downside, you may ask, you dont get on the high scores list.



step 5cheating
alright, if you really do want to cheat minesweeper, then type in this before you start playing : xyzzy (now while holding shift) , what this des is make the very upermost pixel of the screen turn black while you are over a mine. you have to look very closely to see it but it is there.


FINAL NOTES AND TIPS SECTION:

if you are having trubble keeping up with the timer, click on the smilyface but do not let go of the mouse. then drag the mouse to where you want to click next then relese and click...WARNING, if you let go while on the smialy face it will restart your game...so dont do that...


Hacking Flash Games High Scores

If you use Firefox, you can submit outrageous flash game scores to online high score tables.


step 1Extension
You must have this extension for Firefox
https://addons.mozilla.org/firefox/966/
It's called Tamper Data and it lets you modify submitted data, such as a score.


step 2Play the game
Play the flash game, and die. Then run Tamper Data (Tools ==> Tamper Data), then click Start Tamper.

Now click submit or whatever button in the flash game that lets you submit your score.




step 3Change the data
You should get an automatic alert that data is being submitted, and you can choose to tamper with the data, or leave it along, or abort the submission. Click "tamper", and then a window should be opened with lots of data to change.
You want to look for "post data" or something like that on the right, there will be a box with text you can change, look for score and change your score, press ok, and confirm if you get a confirm request.
You are done, your high score should be posted.















Use your gmail account for storing your files easily with a kind of ftp manager for gmail

Much people use there gmail account for storing files. But when you have to send a e-mail everytime you want to store something it can get very annoying. But, theres a solution...G-SPACE....this firefox extension can be used as a kind of ftp manager for uploading and downloading files at your gmail-account.



step 1get firefox
If you don't have firefox you should download and install it. Go to http://www.mozilla.com/en-US/firefox/ and download the file, then install it.

The extension will also work on the portable version of firefox, take a look at my other instructable if you want to know how to get it. http://www.instructables.com/id/ES5WSDTUODEWZMJEGX/


step 2get the extension
Once you've got firefox you can download the extension. You have to open firefox and then download it.

So, open this window in firefox, then go to this site: https://addons.mozilla.org/firefox/1593/ . Then click the download button. If everything is allright there will pop up a window, you'll have to wait 4 seconds and then click install. The extension will be installed and then you'll have to restart firefox.



step 3make a label at your gmail account
When you are going to use the application there will be send e-mails to your gmail-account. You don't want a new e-mail for every file you upload so we will make a filter and we'll ad a label to it.

-go to your gmail account
-go to settings
-go to labels
-create a new label named gspace (picture, removed some personal information)
-a new label has born, congratulations!



step 4create a filter
now we're going to create a filter, go to:settings->filters

-click: create a new filter
-then fill in:

From: youremail@gmail.com
To: youremail@gmail.com
Subject: d$

-then click next step

-check: skip the inbox
-apply a label, then click gspace(the label you've just made)

-then click create filter


step 5start the extension and set your account up.
once we've got the filter it's time to use the extension.

-go to tools-->Gspace
-go to manage accounts
-fill in your username and password
-then click add
-then click close
-choose your account and then click login


Now it's time to use the program....
at the beginning there will be no files at your gspace, you can put them in by selecting a item at the left box and than click the arrow to the right... an e-mail will be send, but not in your inbox, so you won't see it. When you are looking up for a file and you don't have gspace you can always search for it. the file is sent as an attachment. you can also get the file back by going to your gspace and send the file back tou your computer.


Monday, November 26, 2007

AutoRun.inf Tweaking

The autorun.inf file is the key to getting your USB drive (or CD-ROM drive, for that matter) to perform certain actions automatically and customize it’s look in My Computer. The purpose of this article is to shed some light on how this can be done.

Autorun.inf Structure

The autorun.inf file is a simple text file that can be opened up in any text editor (e.g. notepad). It always starts with a section header of:

[autorun]

Below this header is a list of different options. Each of these options is in the following format:

option=value

where

option is the option that you want to set and value is the value that you are setting for that option. So, if you had an option foo and you wanted to be set to bar, then you would enter:

foo=bar

(Do not use foo=bar in your autorun.inf file as it is only an example, not a real option setting.)

That is all there really is to understand about the structure of an autorun.inf file. On to doing some actual cool stuff with it!

Setting a Custom Icon

To create a custom icon for your USB drive, use the icon option. Set it to the name of the icon file.

Note: Since drive letters can change for USB drives, the file path is relative to the root of the drive. This means that if your USB drive is presently mounted on U: and your icon is located at U:\Icons\MyIcon.ico, then you would enter \Icons\MyIcon.ico for the value of this option.

For example, if you had an icon on the root of the USB drive called icon.ico and you wanted this to be the icon that showed up for the USB drive, you would enter:

icon=icon.ico

You are not limited to .ico files. If, for example, you have an executable with a nice icon, you can specify it as the icon file. For example:

icon=open.exe

This is valid as long as open.exe is available on the root of the USB drive.

Some files have more than one icon embedded in them. If this is the case, you can select which icon to use by specifing the index number after the file name. For example:

icon=iconlib.dll,2

This will use the second icon in the iconlib.dll file.

Naming Your USB Drive

If you would like your USB drive to display a specific name othr than the drive label created when it is formatted, use the label option. For example, if I wanted to call my drive Palm Drive, I would add this to my autorun.inf file:

label=Palm Drive

Now, when you look at your USB drive in My Computer, it will say Palm Drive by the drive letter.

Setting AutoPlay Options

AutoPlay is a relatively new function of Windows XP. It allows you to set up what file is run when the USB drive is plugged into the computer and the message that you are prompted with. There are two options that work in conjunction with AutoPlay. The first is open. It specifies the program that you can run automatically with AutoPlay. So, if we wanted to run a program called open.exe, you would add the this to your autorun.inf file:

open=open.exe

The second option that we add is the message the user is prompted with. To set this, we use the action option. If we want the message to say Open Program, add the following to autorun.inf:

action= Open Program

Once you have added this information, AutoPlay should look something like this:

AutoPlay

Adding Context Menu Items

There are certain basic options such as Open and Explore that are available when you right click on a USB drive. But, wouldn’t it be cool to add your own? You can using a couple of lines in the autorun.inf file.

The first thing that we need to do is create an action, give it a name, and a message. We do all of this using the shell\verb option. For example, let’s say that we would like to create an action called lost. It does not matter what the actin is called. It can be anything you want. We would also like to show the message Help! I’m Lost! in the context menu. We would simply add this line to autorun.inf:

shell\lost=Help! I'm Lost!

This will display Help! I’m Lost! in the context menu so that you can click on it. But, it doesn’t know what to do when you click on it. Tell the system by using shell\verb\command option. In our example, we want to run the Lost.exe application. Adding this line will do the trick:

shell\lost\command=Lost.exe

You can add as many of these line pairs as you want to make the context menu as custom as you want.

Changing Default Action

When you double click on your USB drive, by default it will open up the drive so that you can browse through the files. Often, it is advantageous to perform some other action when the user double clicks the USB drive icon. You do this with the shell option. If we wanted to run the Lost.exe program from the previous section automatically when we double clicked on the USB drive, we would add this line:

shell=lost

because lost is the name of the action that was specified in the earlier lines.

Viewing a File

If you wanted to view a file on your USB drive in the default application instead of running a program on the drive, you can substitute the open option for the shellexecute option. For example, if you wanted to open up a website called, oh, I don’t know, say http://sumesh-palm.blogspot.com/ in the default web browser, you could user the following:

shellexecute=http://sumesh-palm.blogspot.com/

This will work for any file. This is the equivalent of using Start - Run… and then typing in a file name and clicking OK.

Tuesday, November 20, 2007

Firefox on Your Flash Drive

Firefox Portable is a great app that lets you run Firefox off of your flash drive. This is great for people who just don't like to browse the web without their extensions, bookmarks etc. It's not slimmed down at all, it works with all your extensions. You can take your customized Firefox to school, work, or anywhere. It doesn't leave behind any personal data. If you want to transfer all of your settings, extensions, and passwords from your stationary Firefox to portable Firefox, follow the instructions

Installing Firefox Portable

To install Firefox Portable, just download the portable package at the top of the Firefox Portable page and then double-click it. Select the location you wish to install to and click OK. A FirefoxPortable directory will be created there and all the necessary files installed. That's all there is to it.

Using Firefox Portable

To start up Firefox Portable, just double-click FirefoxPortable.exe file where you installed Portable Firefox on your portable drive. Then, use it just like you would a local copy of Firefox. There are a couple of things to keep in mind:

  • Stay Safe - When using portable apps, it's always a good idea to practice Safe Portable App-ing.
  • Removing Your Drive - When you're done, exit Firefox and then wait for the activity light on your removable drive to stop flashing. This may take a minute or more on slow drives or computers. Then select the 'Safely remove [device]' option from the icon in the system tray. If you remove the drive while it is writing, you may lose data.

Upgrading Firefox Portable

To upgrade to a newer version of Firefox Portable, just install a new copy of Firefox Portable right over your old one. All your data will be preserved.

If you're upgrading from Portable Firefox (older name and directories), make a copy of your existing profile folder within the PortableFirefox\Data\profile directory on your portable drive. Then download the new version of Firefox Portable and copy your profile from the old version into the new version within FirefoxPortable\Data\profile. If you added any plugins or searchplugins, you should copy those directories as well (PortableFirefox\plugins to FirefoxPortable\Data\plugins and PortableFirefox\firefox\searchplugins to FirefoxPortable\App\firefox\searchplugins).

Copying Your Local Firefox Settings

If you're using a local copy of Firefox, you may wish to just copy your local Firefox settings right into Firefox Portable. Your local Firefox profile is usually installed in C:\Documents and Settings\[user]\Application Data\Mozilla\Firefox\Profiles\default.???\ Just copy the contents of that folder (except the cache directories) to the FirefoxPortable\Data\profile directory. Then, and this is important, delete the file FirefoxPortableSettings.ini within the FirefoxPortable\Data\settings directory, if there is one. When you start Firefox Portable for the first time, it's recommended that you turn off disk cache, password saving and history if you're using a flash-based portable device. You can set all of these within the Privacy tab of the Firefox Options window. Sometimes, certain profiles will cause the launcher to fail or hang. It's best to give it a few minutes to see if it's just checking compatiblity and adjusting the locations of the extensions before giving up on it. If it fails, it is usually due to an incompatible extension.

Installing Plugins (Flash, Shockwave, etc.)

With Firefox Portable, plugins work a bit differently than they do in regular Firefox. Here's how to do some of the most common plugins:

  • Flash Plugin - To install Flash, follow these steps:
    1. Flash is available as an extension. Just click the link.
    2. You'll probably see a yellow bar across the top of the browser (if not, skip to Step 5), on that bar, click Edit Options
    3. In the popup window, click Allow to add PortableApps.com to your whitelist and then click close
    4. Now try the link again
    5. You'll see a popup asking if you would like to install, click OK after the countdown and follow along the prompts
  • Shockwave Plugin - To install Shockwave, follow these steps:
    1. Download the free Shockwave Player from the Macromedia website
    2. Run the installation routine and, instead of letting it install to a local browser, select to choose your browser
    3. Browse to X:\FirefoxPortable\App\firefox (where X is your device's driver letter) and continue with the installation
    4. You may need to restart Firefox Portable for the changes to take effect
  • Other Plugins - Other plugin directions are coming soon...

If the above fails, try the alternate (and more geeky) method:

  1. Install the plugin in a local copy of Firefox (on your hard drive)
  2. Locate your plugins directory (usually C:\Program Files\Mozilla Firefox\plugins\)
  3. Copy the plugin you need from there to your FirefoxPortable\Data\plugins directory (Some Exmaples: For Flash, copy NPSWF32.dll... for Shockwave, copy np32dsw.dll)

Notes: It should be noted that Adobe Flash does *not* officially support running in any portable configuration. And, as it is a closed source application, we can neither modify it nor package it into a more portable-friendly installer. It should also be noted that it is illegal to redistribute either flash or shockwave without the full installer.

Configuring Helper Apps (PDF reader, document viewers, etc)

Firefox Portable supports the ability to set other portable apps as helper apps to handle additional document types even as you move between PCs. So, you can set Sumatra PDF Portable as your PDF viewer, OpenOffice.org Portable as your DOC opener and VLC Media Player Portable as your AVI handler and it will all work as you move to other PCs.

The setting to do this in Firefox Portable works just like it does in a regular install of Firefox:

  1. Click Tools and then Options from the menu
  2. Select the Content tab
  3. Within the File Types section, click the Manage button
  4. In the list of types, select the one you wish to edit and click the Change Action button (if you don't see the type you want, see the note below)
  5. Select the "Open them with this application" radio button and then click Browse
  6. Select the portable app you'd like to open this file type with (example: SumatraPortable.exe)
  7. Click Ok. Click Close. And click OK to close all the windows.

Now, when you click on a file of that type in Firefox, it will open it in the portable app you selected. The PortabableApps.com Launcher takes care of any needed changes as you move between PCs.

Note: If you don't see the file type you'd like in the list of file types, that means Firefox doesn't know about it yet. Just search for a file of that type in Firefox and click on it. It'll either ask you what you'd like to open it with (in which case, just select the portable app you'd like to use) or it will automatically associate it with an application or plugin installed on the local PC. At that point, you can then follow the instructions above to tell Firefox to use a portable app to open that type of file.

Mailto Note: Mailto links are not controlled by Firefox's mimetypes setup, so this has no effect on being able to click on an email link and launching Thunderbird. Firefox simply passes mailto links to Windows and has it open the default mail client.

Privacy Note: When Firefox hands off a file to another application, it will usually store that file in the local PC's TEMP directory. This file may be left behind after you close Firefox Portable.

Improving Firefox Portable's Performance

Firefox Portable runs quite well from faster flash drives (and portable hard drives or iPods) when connected to a USB 2.0 port. But what if your flash drive is a bit below average speed-wise (and just because it says "USB 2.0" on it, doesn't mean it's fast)? Or what if you're stuck connecting to USB 1.1 ports at work or school? Well, there are a few ways to improve performance.

First off, it helps to realize why things are slow. Firefox Portable has to read and write bits of data to and from your portable device while it's running. On most flash drives, every time something is written, all reads stop. When this happens, Firefox Portable can appear to "freeze" or "hesitate" momentarily. Add to this the fact that most flash drives aren't as fast as they promise. They all say "USB 2.0 high speed" on them, but they're actually limited by the speed of the memory chips inside them and the controller chip that handles communication between those chips and a PC. There's about a 40x speed difference between a slow drive and a fast drive when dealing with writing small amounts of data. And, even if a drive can write a 5mb MP3 file quickly, it may be slow with writing lots of tiny files.

Here's a list of different things you can do to speed things up:

  • Disable Cache, History and Form Saving - Cache is disabled by default. In newer releases of Firefox Portable, history and form saving are enabled. You can disable these within the Options window.
  • Disable Session Restore / Undo Close Tab - Firefox 2.0 introduced a new feature called session restore. It keeps track of all your open windows and tabs and can restore your session if Firefox should crash. While a handy feature, it does have the unfortunate side effect of writing to disk on every page load, which slows down Firefox Portable. There's no option to disable it in the usual Tools - Options windows, but you can disable it manually.
    1. In Firefox's address bar, type in about:config and then hit enter
    2. Right-click on any entry and select New - Boolean
    3. For the name, enter browser.sessionstore.enabled and click OK
    4. Select false and then click OK
    When you restart Firefox, session restore (and undo close tab) will be disabled and you should notice an improvement in browsing speed.
  • Disable Anti-Phishing - Firefox 2.0 comes bundled with an anti-phishing filter that warns you of fake sites pretending to be things like ebay and bank login pages. As with the ression restore, though, it results in additional writes to the drive. This is especially noticable in the first few minutes of using Firefox Portable as it has to download the anti-phishing database and store it within your profile (a 3mb+ file). You can disable this feature by clicking Tools - Options and then selecting the Security tab. Uncheck the box next to "Tell me if the site I'm visiting is a suspected forgery" and then click OK. The anti-phishing filter is now off. If you'd like to get back the space taken up by the database of forged sites, exit Firefox Portable and then head to the FirefoxPortable\Data\profile directory on your drive. Delete the urlclassifier2.sqlite file.

Configuring Proxies

As you move between different computers, you may encounter systems on networks that use proxies and don't allow direct access to the internet. You'll need to update Firefox Portable' connection settings to use in the new environment. You can find these settings within Tools - Options - General - Connection Settings. If you routinely use PCs with different proxy settings (for example, work and home or work and school), you can set up the options for both and easily switch between them with the SwitchProxy extension. If you need to determine the connection settings of the PC you are on to add to Firefox Portable, just run our Proxy Get Utility and it will let you know what they are.

Running From a CD (Firefox Portable Live)

Firefox Portable supports running from a CD right out of the box, and it's a snap. Start off by downloading and installing Firefox Portable to your hard drive... it doesn't matter where. Run it at least once to generate the default settings. Then, customize it as needed, being sure not to move FirefoxPortable.exe or any of the other critical files. Next, download FirefoxPortable.ini and save it to the same directory as FirefoxPortable.exe. Then, burn the whole FirefoxPortable directory to a CD and you're ready to go.

If you use Firefox Portable from a USB flash drive with a write-protect switch, you're covered, too. The Firefox Portable Launcher will automatically detect when you protect the drive and offer to run your files locally for you.

Additional information about the options in the INI is provided in the readme.txt file within the FirefoxPortable\Other\FirefoxPortableSource directory. Please note that you must follow Mozilla's Trademark Distribution Guidelines if you are distributing your customized version to anyone else.

Known Issues

The following are known issues with this package:

  • Trojan/Virus detected - AntiVir and Avast, on more than one occasion, have claimed there is a trojan or virus in the launcher. This is due to poor detection in both products that will occasionally mis-identify many NSIS-based applications as trojans. It will usually occur after a definitions update. You should contact your antivirus provider and let them know of their mistake. Do not contact me about it as I am well aware of Avast and AntiVir's issues and can do nothing to fix them. You can either wait for them to fix the issue again or switch to a better antivirus package.
  • Renaming FirefoxPortable.exe - Once on your portable device, the launcher can be renamed to anything you'd like except for firefox.exe. It tries to detect an existing instance of Firefox so it doesn't just launch a new local one and if it is named firefox.exe, it will detect itself.
  • Themes and Extensions - Most themes and extensions should now work with Firefox Portable -- including those that make use of the component registry. A handful will still fail, though. A few things to keep in mind:
    • Some XPIs must be downloaded to your PC before installing and then opened using FILE and then OPEN (this is a limitation of Firefox, see Bug 262854). If you can't easily download the XPI locally (like with the Google Toolbar), simply enable your cache temporarily (Tools - Options - Privacy - Cache - enter 1000 and click OK) and then install the extension. Don't forget to disable the cache again after installing. Oddly, addons.mozilla.org doesn't seem affected by this.
  • No Portable Java - Sun's Java VM needs to be installed locally as it makes a slew of registry entries, etc. There is no way to make it portable at present, so you will only be able to use Java-enabled sites on machines that have the Sun Java VM installed locally.
  • Read/Write Required - Both the Firefox directory and the Profile directory must be writeable on the USB drive. Drives with a writable switch can not be in read-only mode.
  • Network Drives - There has been a report that Microsoft patch MS051-011 may break the ability to run applications from networked drives and that Firefox Portable is affected.
  • Non-ASCII Character Directories Fail - Firefox Portable will not function correctly when placed in a directory containing non-ASCII characters. Firefox Portable's entire path must be ASCII characters. The workaround is, of course, to use an ASCII path for Firefox Portable. In a situation where this is not possible (for example, when being placed on a desktop of a non-English machine), you can set Firefox Portable to run in Windows 98 compatibility mode under Windows XP. (Thanks Wigaldlinger)

Monday, November 19, 2007

Getting a User's Attention in Your Palm OS Applications


Alarm and Attention Managers

Even though Palm OS is not mainly a multitasking system, you definitely experienced the situations when, for example, reminders pop up to inform you about meetings, or an SMS message was just received, and so forth. Palm OS provides several managers that may be used together, to get full control over notifying the user about various events occurring in the system. Again, under term "event" I mean everything that needs a user's attention. So, coming back to formal definitions, Palm OS has Notification Manager, Attention Manager, and Alarm Manager. Notifications were discussed in previous articles, so here we will deal with Attentions.

Attention Manager is a mechanism by which your application can buzz the user if it has something to tell him. If, for instance, you develop a driver, you can interact with the user from the driver's callback functions if needed. Besides, some applications work with communication devices that have no user interface, so Attention Manager features is a way to go. It is important to notice that Attention Manager itself is responsible only for interactions with user rather than events generation. Hence, it is usually used in conjunction with other managers (like Alarm Manager) to perform desired functionality.

Alarm Manager handles real-time monitoring to detect when some point in time was reached. It can be used to perform periodic tasks or show alarms at the appropriate time. In the last case, an application is responsible for providing any required user interface because Alarm Manager doesn't have one on its own. The same is correct for sounds and other effects. You also may use Attention Manager to signal to the user about an event that occurred.

In the following sections, you will see how to use both managers in more detail.

Working with Attention Manager

Attempts types

To get started, let us take a look at different types of attention-getting attempts. The Palm documentation defines two of them: "insistent" and "subtle." They are actually the same, but differ in the manner of "irritation" the user experiences in each case. Insistent attempts interrupt the regular working flow—by producing special effects to gain your attention. Subtle attempts behave like an additional indicator on the screen to inform you about less-critical events—incoming e-mail or an SMS message. This type of attempts doesn't usually use any special effects.

Let me briefly overview each type of Attention. As was stated, an Insistent attention tries to catch the user's eye, so Attention Manager displays a dialog. You may find two types of them: Details and List.

Areas within red rectangles are drawn by the application that performs this attempt. Attention Manager will provide just a dialog box and draw a title and buttons. The function of all buttons on forms is intuitively clear from their titles. The user can accept, snooze, clear, or go to an attention item. All the rest is up to you. It will take you only a few minutes playing around with such alerts to understand all the available options.

The first picture shows an alert set to be risen at specified time. The second one illustrates the situation when several events have occurred, and now there is a list of them. To reach the details of each event, simply tap it. When may this happen? For example, when another application tries to get the user's attention. Here, your program is able to paint an icon and couple of text lines. Please note that the checkbox is provided by Attention Manager.

Events that were snoozed will be redisplayed again after some time. Attention Manager has the only "snooze" timer, so if you select this option, it will influence all events as a whole. Also, to ensure that the user will pay attention to the displayed dialog, any soft- and hardware buttons are disables at that moment.

Another type of attention attempt is subtle one. You can see an example in the following picture:

Every standard form with a title will show a blinking indicator (I've marked it by red color), except in the following cases:

  • Attention Manager's queue is empty
  • Modal Dialog style is used for the title
  • The title is too narrow to show anything else
  • The application draws in the title area
  • A custom title is used

Besides, the indicator will blink in a different manner depending on whether the user has seen all notifications or not.

Wrong Usage Scenarios

The Attention Manager was designed for specific usage. Its intended goal is to provide a mechanism for gaining the user's attention in cases that don't require immediate reaction. You can treat it as some convenient way to remind or inform the user about important but suspendable events. For emergency cases, it is not a way to go.

Next, Attention Manager doesn't deal with displayed items themselves, so dismissing the reminder doesn't influence actual data. Attention Manager should not replace regular error messages that are displaying. Thus, use it as it was supposed to be.

Move to the Code

Bringing Your Information up to the User's Attention

Now, having all this theory in mind, you are ready to code some meaningful example. First of all, look at the available Attention Manager's functions:

Err AttnGetAttention (UInt16 cardNo, LocalID dbID, UInt32 userData,
AttnCallbackProc *callbackFnP,
AttnLevelType level, AttnFlagsType flags,
UInt16 nagRateInSeconds,
UInt16 nagRepeatLimit);
Boolean AttnUpdate (UInt16 cardNo, LocalID dbID, UInt32 userData,
AttnCallbackProc *callbackFnP,
AttnFlagsType *flagsP,
UInt16 *nagRateInSecondsP,
UInt16 *nagRepeatLimitP);
Boolean AttnForgetIt (UInt16 cardNo, LocalID dbID, UInt32 userData);
UInt16 AttnGetCounts (UInt16 cardNo, LocalID dbID,
UInt16 *insistentCountP, UInt16 *subtleCountP);
void AttnListOpen (void);
void AttnIterate (UInt16 cardNo, LocalID dbID, UInt32 iterationData);
Err AttnDoSpecialEffects(AttnFlagsType flags);
void AttnIndicatorEnable(Boolean enableIt);
Boolean AttnIndicatorEnabled(void);

As you see, there are quite a few functions. Your interest will be focused on the first two functions; these allow you to generate and update an Attention attempt. They both have similar parameters, and the first three uniquely identify the attention attempt.

Let me briefly discuss the rest of the parameters. AttnCallbackProc *callbackFnP is a pointer to the callback function that is called by Attention Manager in response to various user reactions or when an attention item is to be redrawn. If this parameter is NULL, Attention Manager will send a sysAppLaunchCmdAttention launch code to your application instead of calling a callback function. AttnLevelType level allows you to select either an kAttnLevelInsistent or kAttnLevelSubtle attempt type. AttnFlagsType flags tell Attention Manager which effects to apply for a given item. You can use sound, LED blinking, vibration, or some custom effects. These flags also command the Attention Manager how to relate to the default behavior defined in the general user's preferences. And finally, the last two parameters control nagging stuff. AttnUpdate, in addition to AttnGetAttention, allows you to update an existing attention item; for example, you can assess a new callback procedure or change all other parameters.

A decision of which 'notification' method (callback or launch code) to choose for specific situation highly depends on a structure of your application. For relatively small programs, it doesn't matter at all; but for large projects, the callback funtion may cause some problems. The matter is that you have to be sure that at the moment Attention Manager calls your callback this particular code segment is still available; in other words, located at the same memory address or was not deleted. The launch codes mechanism usually doesn't result in such scenarios.

Before you glance at the code sample, let me note a couple of simple functions: AttnForgetIt and AttnIterate. The first one is used to inform Attention Manager that a given item is no longer relevant, so Attention Manager may forget about it. Usually, you will call it in response to a "Go To" button press—when a user has decided to look into your attention item. AttnIterate causes the Attention Manager to call a callback routine or send a launch code for every pending item that matches a given cardNo and dbID. Such iteration may be required, for instance, after a HotSync session and so forth to update pending attentions.

Well, let me start with samples. First, the Attention callback function is listed below:

static Err AttnCallbackFunc(AttnCommandType command,
UInt32 userData,
AttnCommandArgsType *commandArgsP)
{
char szText[] = "Visit Developer.com";
if ( kAttnCommandDrawDetail == command )
{
Coord x = commandArgsP->drawDetail.bounds.topLeft.x;
Coord y = commandArgsP->drawDetail.bounds.topLeft.y;
Coord w = commandArgsP->drawDetail.bounds.extent.x;
MemHandle resH = DmGetResource(bitmapRsc, TestBmp);
WinDrawBitmap((BitmapType*)MemHandleLock(resH), x, y + 3);
MemHandleUnlock(resH);
DmReleaseResource(resH);
FontID curFont = FntSetFont (largeBoldFont);
WinDrawTruncChars(szText, StrLen(szText),
x + 27,
y + 3,
w - x);
FntSetFont (curFont);
}
else if ( kAttnCommandDrawList == command )
{
Coord x = commandArgsP->drawList.bounds.topLeft.x;
Coord y = commandArgsP->drawList.bounds.topLeft.y;
Coord w = commandArgsP->drawList.bounds.extent.x;
FontID curFont = FntSetFont (boldFont);
WinDrawTruncChars(szText, StrLen(szText),
x + 3,
y,
w - x);
FntSetFont (curFont);
}
else if ( kAttnCommandGoThere == command )
{
Err err;
UInt16 cardNo;
LocalID dbID;
err = SysCurAppDatabase(&cardNo,&dbID);
AttnForgetIt(cardNo, dbID, userData);
}
else if ( kAttnCommandPlaySound == command )
{
SndPlaySystemSound(sndWarning);
}
return errNone;
}

This callback receives full info about what Attention Manager wants from the recent attention item and acts accordingly. It means that the callback knows what a command is, what the drawing area is, and so forth. Actually, the same function is called from the launch code handler.

The next code snippets illustrates a usage of different API to get user's attention, update pending items, and so forth:

static Boolean OnGetAttn()
{
Err err;
UInt16 cardNo;
LocalID dbID;
err = SysCurAppDatabase(&cardNo,&dbID);
err = AttnGetAttention(cardNo, dbID,
g_nEventID++,
AttnCallbackFunc,
kAttnLevelInsistent, kAttnFlagsAlwaysLED,
300, 10);
return true;
}
static Boolean OnGetSubtleAttn()
{
Err err;
UInt16 cardNo;
LocalID dbID;
err = SysCurAppDatabase(&cardNo,&dbID);
err = AttnGetAttention(cardNo, dbID,
g_nEventID++,
AttnCallbackFunc,
kAttnLevelSubtle, kAttnFlagsAlwaysLED,
300, 10);
return true;
}
static Boolean OnUseLaunchCode()
{
Err err;
UInt16 cardNo;
LocalID dbID;
err = SysCurAppDatabase(&cardNo,&dbID);
err = AttnGetAttention(cardNo, dbID,
g_nEventID++,
NULL,
kAttnLevelInsistent, kAttnFlagsAlwaysLED,
300, 10);
return true;
}
static Boolean OnUpdateAttn()
{
Err err;
UInt16 cardNo;
LocalID dbID;
UInt16 nagRateInSeconds = 30, nagRepeatLimit = 2;
AttnFlagsType flags = kAttnFlagsAlwaysSound;
err = SysCurAppDatabase(&cardNo,&dbID);
err = AttnUpdate(cardNo, dbID,
g_nEventID-1, // for the last attention only
AttnCallbackNewFunc,
&flags,
&nagRateInSeconds, &nagRepeatLimit);
return true;
}

For simplicity, all these functions increase userData parameter at every call. In real situation you can apply your own logic here.

Let me discuss one scenario when you might want to dismiss the Attention Manager dialog completely. This is not so rare a case as you might think. Suppose that you handle extansion cards' insertion or removal or any hardware events that may occur while the Attention Manager dialog is open for some reason. In response to such incoming notifications, you can call the AttnForgetIt function to get rid of some pending attention items. The problem is that the whole dialog will remain on the screen regardless of how many items are left there. So, in the worst case, Attention Manager's dialog will be empty. Naturally, you would like to close it somehow. The simplest way to do it is to simulate a button tap on this dialog so that FrmDoDialog will exit:

// Get recently active form
FormType *frmP = FrmGetActiveForm();
UInt16 defaultButtonID = FrmGlueGetDefaultButtonID(frmP);
// Create new event and place in to the event queue
EventType newEvent;
MemSet(&newEvent, sizeof(newEvent), 0);
newEvent.eType = ctlSelectEvent;
newEvent.data.ctlSelect.controlID = defaultButtonID;
newEvent.data.ctlSelect.pControl = (ControlType*)FrmGetObjectPtr(frmP,
FrmGetObjectIndex(frmP,
defaultButtonID));
EvtAddEventToQueue(&newEvent);
// and finally dismiss an item
AttnForgetIt(cardNo, dbID, userData);

Making Special Effects

As I have noted above, you can request some special effects upon generating an attention item; for example, LED blinking, vibration, playing a sound, or any other custom effect. A good practice is to verify whether the PDA has desired capabilities, for instance as follows:

UInt32 caps;
FtrGet(kAttnFtrCreator,kAttnFtrCapabilities,&caps);
if ( caps & kAttnFlagsHasLED == kAttnFlagsHasLED )
{
// set appropriate flags
}

If you have a requested sound effect, Attention Manager will send a kAttnCommandPlaySound command. Your application, in turn, may the play sound based either on user's preferences or its own using Sound Manager; say, calling SndPlaySystemSound as a simplest example.

If you have specified a kAttnFlagsAlwaysCustomEffect flag, you'll be able to surprise the user by producing something gorgeous in response to a kAttnCommandCustomEffect command. Anyway, in both cases, the system doesn't inform you which sound to play or what is a special effect. You have to store it in the application's preferences or hardcode it.

Download

Download the accompanying code's zip file here.

How Palm OS Expands Your Applications: Expansion Manager


Expansion Manager, to confirm its name, is a layer that manages slot drivers. Actually, it doesn't work with slots directly. Instead, Expansion Manager provides unified APIs to manupilates slots. All specific 'magic is performed by appropriate slot driver implemented as a shared library. Such architecture is similar to VFS Manager .



UInt32 nValue = 0;

if ( ftrErrNoSuchFeature == FtrGet(sysFileCExpansionMgr,

expFtrIDVersion, &nValue) )

{

// Nothing to do...

}

else

{

// Check here required minimal Expansion Manager Version

}

Slot Enumeration and So Forth

As with many other managers, the very first step is usually some kind of enumeration process. Your application needs to know which slots are presented in the system. Hence, the slot number is a base stone in all further operations. The following tiny snippet shows all the required code to obtain available slots:



UInt16 slotRefNum = -1;

UInt32 slotIterator = expIteratorStart;

while (slotIterator != expIteratorStop)

{

if ( errNone == (err = ExpSlotEnumerate(&slotRefNum,

&slotIterator)) )

{

// slotRefNum to be used later

}

else

{

// error occured

}

}

After the slot number is detected, there are a number of operations you can accomplish. I will start with the simplest one:

Err ExpCardPresent(UInt16 slotRefNum)

This function verifies whether a card is presented into specified slot. errNone indicates success; in other words, the card is in. All other return codes will flag appropriate an error; for example, expErrCardNotPresent.

Your application may need to gather more info about a card in a slot. The following simple function provides this data:

Err ExpCardInfo(UInt16 slotRefNum, ExpCardInfoType *infoP)

A code sample below displays one possible scenario:



/* Excerpt from ExpansionMgr.h

typedef struct ExpCardInfoTag

{

// bits for different stuff the card supports

UInt32 capabilityFlags;

// Manufacturer, e.g., "Palm", "Motorola", etc...

Char manufacturerStr[expCardInfoStringMaxLen+1];

// Name of product, e.g., "SafeBackup 32MB"

Char productStr[expCardInfoStringMaxLen+1];

// Type of product, e.g., "Backup", "Ethernet", etc.

Char deviceClassStr[expCardInfoStringMaxLen+1];

// Unique identifier for product, e.g., a serial number.

// Set to "" if no such identifier exists.

Char deviceUniqueIDStr[expCardInfoStringMaxLen+1];

}

ExpCardInfoType, *ExpCardInfoPtr;

*/

...

ExpCardInfoType CardInfo;

if( errNone == ExpCardInfo(slotRefNum,&CardInfo))

{

HostTraceOutputTL(appErrorClass,"Capability: %snManufacturer:

%snName: %snClass: %s",

(const char*)GetCapability(CardInfo.capabilityFlags),

CardInfo.manufacturerStr,

CardInfo.productStr,

CardInfo.deviceClassStr);

}

else

{

// process error

}

...

CString GetCapability(UInt32 capabilityFlags)

{

CString sInfo;

if ( capabilityFlags & expCapabilityHasStorage )

sInfo += " Has Storage";

if ( capabilityFlags & expCapabilityReadOnly )

sInfo += " Read Only";

if ( capabilityFlags & expCapabilitySerial )

sInfo += " Serial Interface";

return sInfo;

}

As you can see, the received struct contains important info regarding card capabilities and class, so you always will be able to determine what your application can do with this particular storage or whatever it is.

If the expansion card supports simple serial interface, you can obtain a creator ID to use it later with Serial I/O API calling:

Err ExpCardGetSerialPort(UInt16 slotRefNum, UInt32 *portP)

A typical usage is as follows:



UInt32 port;

if ( errNone == ExpCardGetSerialPort(slotRefNum, &port) )

{

UInt16 newPortId;

err = SrmOpen (port, 19200, newPortId);

...

}

In Palm OS 6 Cobalt, ExpCardGetSerialPort and related stuff were deleted, so yoo should check which OS version you're going to support in your applications.

Inserting and Removing Cards

When expansion cards are inserted to or removed from a slot, Palm OS sends several broadcast notifications to inform all interested parties about the event that occured. Usually, Expansion and VFS Managers register several events on the card's insertion/removal, volume mounting, and so forth. Your application may be required to intercept default handlers. Palm OS gives you a simple way to do it: using notification handlers. A common practice here is to register for desired notifications at program startup and then unregister when it is no longer needed, usually at the exit from the application.

The default sequence of broadcasted events and related stuff upon card insertion are listed below:

  1. The sysNotifyCardInsertedEvent is broadcast by the slot driver
  2. Expansion Manager, registered for this event with priority 20, tries to mount volumes on inserted card with VFSVolumeMount
  3. VFSVolumeMount broadcasts sysNotifyVolumeMountedEvent for each mounted volume
  4. Expansion Manager, registered for this event with priority -20, does its job before any other application with normal priority
  5. VFS Manager, registered with priority 10, handles next two steps
  6. VFS Manager copies start.prc (if such an application exists in the /PALM folder)
  7. sysAppLaunchCmdCardLaunch is sent to start.prc and then sysAppLaunchCmdNormalLaunch
  8. Expansion Manager plays a sound indicating card insertion

Looking at the above list, let me point to where your application can intercept a default flow. There are two main spots. When the user inserts a card into expansion slot, sysNotifyCardInsertedEvent is broadcast. By default, Expansion Manager registers itself to get it with priority 20. This is done to ensure that Expansion Manager will get notified after all other applications registered for the same event with normal priority (sysNotifyNormalPriority). Your new handler should set the appropriate bits in the SysNotifyParamType.handled member:

  • expHandledVolume to prevent Expansion Manager; to deal with volume mounting and unmounting
  • expHandledSound to prevent Expansion Manager; to deal with sound indication on card insertion/removal

If you need only to be notified about these events without any influence on the default flow, just don't set up these two bits, that's all. Applications usually register themselves to volume mount/unmount events rather than to card related stuff, which was initially intended for system use. Nevetherless, sometimes you can be required to handle such kind of events as well.

A similar event chain happens in the case of sysNotifyVolumeMountedEvent. As you have seen already, VFS Manager registers itself to receive volume-related notifications with priority 10. So, if your application was registered for such notifications with normal priority, you always will be able to change the default flow of event handling. Saying so, you might be setting the following bits in the SysNotifyParamType.handled member:

  • vfsHandledUIAppSwitch to prevent VFS Manager from performing an UI switch to start.prc
  • vfsHandledStartPrc to prevent VFS Manager from running start.prc automatically

The volume unmounting and card removal processes flow is similar to insertion, but with several differences. Upon card removal, Expansion Manager informs all subscribers by broadcasting sysNotifyCardRemovedEvent, unmounts all its volumes, and plays a sound to indicate removal. Volume unmounting causes VFS Manager to remove start.prc from heap and send sysNotifyVolumeUnmountedEvent. Your application can be interested to be notified about such events.

The last, but not the least thing, is the security issues here. You should keep in mind one very simple scenario. If the PDA was locked at the time of insertion/mounting notification, your application has not run anything, thus keeping the PDA locked.

Finally, after such a long discussion about different notification codes, let me place a simple schematical code snippet here to illustrate all the things you have learrned:


...

static Err AppStart(void)

{

UInt16 cardNo;

LocalID dbID;

// Get the current application path

SysCurAppDatabase(&cardNo, &dbID);

// Register for desired notifications, they will be sent as

// launch codes (the fourth parameter is NULL)

SysNotifyRegister(cardNo, dbID, sysNotifyCardInsertedEvent,

NULL, sysNotifyNormalPriority, NULL);

SysNotifyRegister(cardNo, dbID, sysNotifyCardRemovedEvent,

NULL, sysNotifyNormalPriority, NULL);

SysNotifyRegister(cardNo, dbID, sysNotifyVolumeMountedEvent,

NULL, sysNotifyNormalPriority, NULL);

SysNotifyRegister(cardNo, dbID, sysNotifyVolumeUnmountedEvent,

NULL, sysNotifyNormalPriority, NULL);

...

return errNone;

}

static void AppStop(void)

{

UInt16 cardNo;

LocalID dbID;

// Get the current application path

SysCurAppDatabase(&cardNo, &dbID);

// Unregister for all notifications

SysNotifyUnregister(cardNo, dbID, sysNotifyCardInsertedEvent,

sysNotifyNormalPriority);

SysNotifyUnregister(cardNo, dbID, sysNotifyCardRemovedEvent,

sysNotifyNormalPriority);

SysNotifyUnregister(cardNo, dbID, sysNotifyVolumeMountedEvent,

sysNotifyNormalPriority);

SysNotifyUnregister(cardNo, dbID, sysNotifyVolumeUnmountedEvent,

sysNotifyNormalPriority);

...

/* Close all the open forms. */

FrmCloseAllForms();

}

...

UInt32 PilotMain(UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags)

{

Err error;

UInt32 locked = 0;

SysNotifyParamType *notifyParamP = NULL;

UInt16 nSlotNumber = 0;

error = RomVersionCompatible (ourMinVersion, launchFlags);

if (error) return (error);

switch (cmd)

{

case sysAppLaunchCmdNormalLaunch:

error = AppStart();

if (error)

return error;

/*

* start application by opening the main form

* and then entering the main event loop

*/

FrmGotoForm(MainForm);

AppEventLoop();

AppStop();

break;

case sysAppLaunchCmdNotify:

notifyParamP = (SysNotifyParamType *)cmdPBP;

switch(notifyParamP->notifyType)

{

case sysNotifyCardInsertedEvent:

nSlotNumber = (UInt16)notifyParamP->notifyDetailsP;

// do whatever you need to

break;

case sysNotifyCardRemoveEvent:

nSlotNumber = (UInt16)notifyParamP->notifyDetailsP;

// do whatever you need to

break;

case sysNotifyVolumeMountedEvent:

nSlotNumber = (UInt16)notifyParamP->notifyDetailsP;

// do whatever you need to

break;

case sysNotifyVolumeUnmountedEvent:

nSlotNumber = (UInt16)notifyParamP->notifyDetailsP;

// do whatever you need to

break;

...

}

break;

}

return errNone;

}

Google
 
PalmProgramming