<!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN"><!-- -*- html -*- -->
<html>
<head>
   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
   <meta name="GENERATOR" content="Lovingly hand-crafted by Torsten">
   <meta name="Author" content="Torsten Bergmann">
   <meta name="Description" content="Win32 Squeak">
   <meta name="Keywords" content="Smalltalk-80, Squeak, Win32">
   <style type="text/css">
     <-- HR { border: solid #639e9c } -->
     H2, H3 { font-weight: bold; color: #639e9c }
     H2 { background-color: #bdd3bd }
   </style>
   <title>Squeak: Win32 Custom Product Building</title>
</head>
<body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#9a0065" alink="#FF0000" font="Arial,Verdana">
<hr>
<table width="100%" bgcolor="white" cellspacing="0" height="52">
  <tr><td width="65" height="52" align="left" bgcolor="white">
        <a href="http://www.smalltalk.org/">
          <img src="balloon_sm.gif" width="62" height="46"
               hspace="10" border="0"></a></td>
      <td align="center" width="100%">
        <table bgcolor="black" width="100%" height="52" cellspacing="1">
          <tr><td bgcolor="#bdd3bd" align="center">
                <font size="+3"; style="font-size: x-large; font-weight: bold">
                  Win32 Custom Product Building</font></td></tr></table></td>
      <td width="65" height="46" align="right" bgcolor="white">
        <a href="http://www.squeak.org">
          <img src="mouse_sm.gif" width="65" height="46" hspace="10" border="0"></a></td>
  </tr>
</table>
<hr>

<br>

If you want to build a product based on Squeak you can easily modify the image and virtual machine to suite your needs. This page provides some basic tips for customizing an application.

<p><table bgcolor="#bdd3bd" width="100%">
  <tr><td cellvalign="center" align="center">
        <font size="+1" color="#639e9c"><b>Preparing the image</b></font></td></tr></table><p>

First load the sourcecode of your application (game, webserver application) into a clean Squeak image file.
Depending on the expected size of the image file you may want to unload or remove packages and classes that
are not required at runtime (this process is called "stripping" an image and can be automated by simple scripts). This can also include all
the tools that are required for development (browsers, test runner, etc.). Take care what you remove and
heavily test the image and application before you ship.<br><br>

<u>Tip:</u> If the size of the image file does not matter it may be wise to keep all the development tools since it allows you to
debug, change or fix your application even in a production scenario.<br><br>

If you want to keep the size of the distribution small you may wish to deploy the prepared application without the changes and source file. Since
Squeak searches for these files at startup by default you may want to disable the two preferences
<i>"warnIfNoSourcesFile"</i> and <i>"warnIfNoChangesFile"</i> (go to <i>help -> preferences -> general</i> to access the preference browser)
<br><br>

You can now save the image with your application already started. Alternatively you can write a special
launcher class that is called at image startup:

<br>
<pre><code>
Object subclass: #ApplicationLauncher
        instanceVariableNames: ''
        classVariableNames: ''
        poolDictionaries: ''
        category: 'MySqueakBasedApp'
</code></pre>

Now implement a new method #startUp at the <u>class side</u> of this new class. Here you can execute whatever is required to launch your application:

<pre><code>
startUp
    "Launch my killer application"
        ...
</code></pre>

Now register your launcher class to be called at image startup by executing the following code in a workspace:

<pre><code>
Smalltalk addToStartUpList: ApplicationLauncher
</code></pre>

When you now save your image your startup code should be called.
<br><br><br>
<p><table bgcolor="#bdd3bd" width="100%">
  <tr><td cellvalign="center" align="center">
        <font size="+1" color="#639e9c"><b>Building a custom virtual machine</b></font></td></tr></table><p>

<a href="compiling.html">Compiling the squeak virtual machine</a> is easier as it sounds in the first place. You can even adapt the source
code so a custom virtual machine is built. To accomplish this follow these steps:

<ul>
        <li>First download and setup the compiler tools as described in the <a href="compiling.html">compiling tutorial</a>
        <li>Download the latest Squeak VM sources file from the <a href="http://www.squeakvm.org/win32/release/?C=M;O=D">win32 releases page</a> and extract it into a directory of your choice
        <li>Now make a parallel copy of the existing directory <i>"winbuild"</i> and name it <i>"myappbuild"</i> for example
        <li>Within this new directory <i>"myappbuild"</i>
        <ul>
                        <li>delete the three *.ico files from squeak (<i>squeak.ico</i>, <i>squeak2.ico</i> and <i>squeak3.ico</i>)
                        <li>copy a custom icon <i>myapp.ico</i> file into the directory
                        <li>edit <i>"Squeak.rc"</i> with a text editor and modify all 3 icon definitions to use your custom <i>"myapp.ico"</i> now
                        <li>copy a custom splash.bmp into this directory
                        <li>edit the file <i>"Makefile"</i> with a text editor and set the name of the new VM to "MyApp" in line 12 ("VM = MyApp"), note the uppercase (since this name is also used as window title and in dialogs by the VM)
                        <li>rename the file <i>"Squeak.def.in"</i> into <i>"MyApp.def.in"</i> (note the uppercase)
                        <li>rename the file <i>"Squeak.rc"</i> into <i>"MyApp.rc"</i> (note the uppercase)
                        <li>run "make" from the command line to build your own virtual machine
        </ul>
</ul>

You will now find a <i>"MyApp.exe"</i> (with the custom icon) and two external plugins (<i>"FT2Plugin.dll"</i> and <i>"SqueakFFIPrims.dll"</i>) in the <i>myappbuild\obj\vm</i> directory.
Depending on your knowledge in Squeak virtual machine generation you can tweak your VM as required.

<br><br>
<u>Tip:</u> To build professional looking icons for Win32 we would recommend the free <a href="http://icofx.ro/">IcoFX</a> editor.

<p><table bgcolor="#bdd3bd" width="100%">
  <tr><td cellvalign="center" align="center">
        <font size="+1" color="#639e9c"><b>Building a distribution</b></font></td></tr></table><p>

Now that you have sucessfully prepared an image and built a custom virtual machine you can assemble your own distribution. First create a directory <i>"myappdist"</i>
and copy the following files into it:
<ul>
<li>"MyApp.image" (the custom image file)
<li>"MyApp.exe" (the custom virtual machine)
<li>"FT2Plugin.dll"
<li>"SqueakFFIPrims.dll"
</ul>

If you start the application by dragging the <i>MyApp.image</i> file onto the <i>MyApp.exe</i> file you will notice that a new file (<i>"MyApp.ini"</i>) is automatically created.
This file includes default settings for the application. You can adapt it according to the <a href="settings.html">settings page</a>.

Depending on your requirements you can include the following additional lines:

<pre><code>
WindowTitle="MyApp"
ImageFile=MyApp.image
</pre></code>

The first one sets a custom text for the applications main window and the second one allows you to specify the image for easier and faster startup.
The interesting thing here is that by setting "ImageFile" you can name the image the way you like - so it is possible to name the image <i>myapp.dat</i> for instance (and hide the fact that the application is built in Smalltalk)
<br><br>
To provide a custom splash screen that is shown at application startup just create a simple bitmap file (<i>splash.bmp</i>) using a drawing program
and provide a few more lines in the INI file:

<pre><code>
SplashScreen="splash.bmp"
SplashTitle="My simple application"
SplashTime=2000
</pre></code>

Depending on your type of application (open source or not) you may want to additionally provide a file <i>license.rtf</i>.<br><br>

You can now package and distribute your application folder as a simple ZIP or follow the next step to build a professional installer.

<p><table bgcolor="#bdd3bd" width="100%">
  <tr><td cellvalign="center" align="center">
        <font size="+1" color="#639e9c"><b>Building a professional looking setup</b></font></td></tr></table><p>

There are many (free) setup tools out there. They allow you to easily built setup wizards and define which files to copy onto a target machine.
One option could be to use the free NSIS (Nullsoft Install System) Tool to write a setup script and compile it into an executable setup.
The setup script is a simple text file with the *.nsi extension.

Here are some basic steps to help you getting started:
<ol>
        <li>download and install the free NSIS installer package, here we use version 2.42 from <a href="http://nsis.sourceforge.net">http://nsis.sourceforge.net</a></li>
        <li>also download the file <i>"ZIPDLL.zip"</i> plugin from <a href="http://nsis.sourceforge.net/ZipDLL">http://nsis.sourceforge.net/ZipDLL</a>. This allows for better compression of the image file.
        <li>extract the file <i>ZipDLL.dll</i> to directory <i>"Plugins"</i> in your NSIS installation
        <li>extract ZipDLL.nsh to directory <i>"Include"</i> in your NSIS installation
        <li>create a file <i>"setup.nsi"</i> file (see below) to your "myappdist" directory and compile it using NSIS (right click on the file and select "Compile NSIS script" from the context menu
        <li>you should now have a <b>"setup_myapp_0.0.0.1.exe"</b> ready for distribution
</li>
</ol>

Assuming that you have the following files in "myappdist" directory:
<br><br>
<table border="1">
<tr><td>setup.nsi</td><td>the install script</td></tr>
<tr><td>license.rtf</td><td>A license file in RTF format</td></tr>
<tr><td>MyApp.dat</td><td>the image file</td></tr>
<tr><td>MyApp.ico</td><td>the icon used for the installer</td></tr>
<tr><td>MyApp.exe</td><td>the custom virtual machine</td></tr>
<tr><td>MyApp.ini</td><td>the settings file for the virtual machine</td></tr>
<tr><td>splash.bmp</td><td>the splash screen</td></tr>
<tr><td>SqueakFFIPrims.dll</td><td>the plugin for FFI (Foreign Function interface) calls</td></tr>
<tr><td>FT2Plugin.dll</td><td>the freetype plugin</td></tr>
<tr><td>welcome.bmp</td><td>a welcome bitmap used in the setup wizard<(164 &star; 314 pixel)/td></tr>
<tr><td>header.bmp</td><td>a header bitmap used in the setup wizard (150 &star; 157 pixel)</td></tr>
</table>
<br>
the contents of the setup script <i>setup.nsi</i> may look like that:

<table border="1"><tr><td>
<pre><code>
/*************************************************************************
 *
 *  NSIS Setup script
 *
 * (c) 2009 by Squeak Community, All rights reserved
 *
 * Requires: NSIS 2.42 http://nsis.sourceforge.net
 *           ZIP DLL   http://nsis.sourceforge.net/ZipDLL
 *************************************************************************/

SetCompressor /SOLID lzma                                ;use LZMA algorithm

###################################
# Includes
###################################
!include "MUI.nsh"
!include "ZipDLL.nsh"

###################################
# Definitions
###################################
; General definitions
!define /date TIMESTAMP "%Y-%m-%d-%H-%M-%S"
!define PROVIDER "Squeak Community"
!define PRODUCT  "MyApp"
!define PRODUCT_LOWERCASE "myapp"
!define VERSION  0.0.0.1
!define URL      "http://www.squeak.org"
!define YEAR     "2009"
!define LAUNCHER "myapp.exe"

!define APP_NAME "${PRODUCT}"
!define REG_KEY  "SOFTWARE\${APP_NAME}"
!define MGROUP   "${PRODUCT}"

; SOURCE Definitions
!define SETUP_NAME "setup_${PRODUCT_LOWERCASE}_${VERSION}.exe"
!define OUTPUT_TARGET "${SETUP_NAME}"

; TARGET Definitions
!define TARGET_DIR "$LOCALAPPDATA\${PRODUCT}"

###################################
# Compiler commands
###################################
Name         "${PRODUCT}"
OutFile      "${OUTPUT_TARGET}"
InstallDir   "${TARGET_DIR}"                             ;Default installation
InstallDirRegKey HKCU "${REG_KEY}" ""                    ;Get installation  from registry if available
RequestExecutionLevel user                               ;Request application privileges for Windows Vista
BrandingText "${APP_NAME} Version ${VERSION}"            ;brand the installer so now NSIS stuff is shown
XPStyle      on
CRCCheck     on                                          ;do a CRC check
SetOverwrite on                                          ;force overwrite
SetCompress force                                        ;force compression


###################################
# Infos for Software control panel
###################################

VIProductVersion 0.0.0.1
VIAddVersionKey ProductName     "${APP_NAME}"
VIAddVersionKey ProductVersion  "${VERSION}"
VIAddVersionKey CompanyName     "${PROVIDER}"
VIAddVersionKey CompanyWebsite  "${URL}"
VIAddVersionKey FileVersion     ""
VIAddVersionKey FileDescription ""
VIAddVersionKey LegalCopyright  "(c) ${YEAR} by ${PROVIDER}"

###################################
# Modern User Interface settings
###################################
; Other Definitions
!define MUI_ICON   "myapp.ico"                                        ; icon for the installer
!define MUI_HEADERIMAGE
!define MUI_HEADERIMAGE_BITMAP "header.bmp"                     ; optional
!define MUI_WELCOMEFINISHPAGE_BITMAP "welcome.bmp"          ; optional
!define MUI_FINISHPAGE_NOAUTOCLOSE                          ; Do not automatically jump to the finish page, to allow the user to check the install log.
!define MUI_UNFINISHPAGE_NOAUTOCLOSE                        ; Do not automatically jump to the finish page, to allow the user to check the uninstall log.
!define MUI_FINISHPAGE_RUN "$INSTDIR\${LAUNCHER}"            ; allows to run the application after install

###################################
# Pages
###################################

;Installer pages
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_LICENSE "license.rtf"
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH

;Uninstaller pages
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES

###################################
# Language
###################################
!insertmacro MUI_LANGUAGE "English"

###################################
# Installer section
###################################
Section "Application" Section1
  SetOutPath "$INSTDIR"
  SetOverwrite on
  DetailPrint "Installation Started."

  File license.rtf
  File MyApp.exe
  File MyApp.dat
  File MyApp.ini
  File splash.bmp
  File SqueakFFIPrims.dll
  File FT2Plugin.dll

  ;Store installation
  WriteRegStr HKCU "${REG_KEY}" "" $INSTDIR
  ;Create uninstaller
  WriteUninstaller "$INSTDIR\Uninstall.exe"

  SetOutPath $INSTDIR
  DetailPrint "Create Program group"
  CreateDirectory "$SMPROGRAMS\${MGROUP}"
  CreateShortCut "$SMPROGRAMS\${MGROUP}\${PRODUCT}.lnk" "$INSTDIR\${LAUNCHER}"
  CreateShortCut "$SMPROGRAMS\${MGROUP}\Uninstall.lnk" "$INSTDIR\Uninstall.exe"

SectionEnd

###################################
# Section description
###################################
LangString DESC_Section1 ${LANG_ENGLISH} "The sample application"
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
  !insertmacro MUI_DESCRIPTION_TEXT ${Section1} $(DESC_Section1)
!insertmacro MUI_FUNCTION_DESCRIPTION_END

###################################
# Uninstaller section
###################################
Section "Uninstall"

SetOutPath $INSTDIR
    DetailPrint "Start uninstalling"

    Delete "$INSTDIR\license.rtf"
    Delete "$INSTDIR\MyApp.exe"
    Delete "$INSTDIR\MyApp.dat"
    Delete "$INSTDIR\MyApp.ini"
    Delete "$INSTDIR\splash.bmp"
    Delete "$INSTDIR\SqueakFFIPrims.dll"
    Delete "$INSTDIR\FT2Plugin.dll"

    ;delete uninstaller
    Delete "$INSTDIR\Uninstall.exe"
    RmDir /r /REBOOTOK "$SMPROGRAMS\${MGROUP}"
    RmDir /REBOOTOK $INSTDIR
    DeleteRegKey /ifempty HKCU "${REG_KEY}"
SectionEnd

#################################
# Utilities
#################################

# Installer functions
Function .onInit
    InitPluginsDir
    Push $R1
    File /oname=$PLUGINSDIR\spltmp.bmp splash.bmp
    advsplash::show 3000 600 400 -1 $PLUGINSDIR\spltmp
    Pop $R1
    Pop $R1
FunctionEnd
</code></pre>
</td></tr>
</table>

<p><table bgcolor="#bdd3bd" width="100%">
  <tr><td cellvalign="center" align="center">
        <font size="+1" color="#639e9c"><b>More tips and tricks</b></font></td></tr></table><p>

<ul>
        <li>if required you can build your own update server (see <a href="http://wiki.squeak.org/squeak/486">this page</a> on the squeak swiki)</li>
        <li>if your application crashes you may want to adapt the debugger to write the stack trace and additional informations on disk or even send an email to the application developers
        <li>if you want to deploy a web application (using seaside or other web frameworks) you may wish to register the virtual machine as a windows NT service
        <li>if you want to restrict the end user only to use your application have a look at preferences and code to disable menus, the cmd-. and halos.
        <li>...
</ul>

</body>
</html>