Click here to Skip to main content
13,588,580 members
Click here to Skip to main content
Add your own
alternative version

Tagged as


13 bookmarked
Posted 27 Feb 2011
Licenced CPOL

Programming User Interface in InstallScript

, 1 May 2011
Rate this:
Please Sign up or sign in to vote.
This article describes advanced techniques for programming user interface in pure InstallScript projects.

Table of Contents


InstallScript language is generally based on C/C++ and InstallScript GUI programming uses Win32 API as its base. Despite that, InstallScript still lacks a lot of Win32 API’s advanced features. Many times, some of its functionality is removed on purpose by producer’s staff to make it more clear and usable for ”dummies” despite the fact that the language syntax can theoretically support it.

InstallScript controls wizard follows the MSI standards and misses a number of standard Windows controls, like an IP Address control, Animation control and many more.
Existing InstallShield controls miss also some control styles which are present in Win32 API, like LBS_NOSEL – a ListView control style (we will go over it later in future chapters).
All these missed controls can be created manually with CreateWindowsEx and be managed by a standard windows messaging mechanism.

A Windows notification catching is another problem.
The WaitOnDialog is a function which is intended to catch dialog events. In DLG_MSG_ALL mode, it passes through to user functions only a limited number (about 10%) of censored control notifications based on WM_COMMAND. The remaining 90% of windows messages probably are considered excessive for “dummies”. No events for static controls (Icons, Images and TextLabels) are allowed because they are automatically set to a disabled state in a resource file and their state cannot be set from the wizard.
Such approach can be found acceptable for Basic MSI projects but not in a pure InstallScript environment. The reason for this is that MSI technology initially intended to support only a limited number of windows features opposite InstallScript which appears to be a fully functional scripting language and actually has very little in common with MSI.

The events shown below are everything I was able to catch in DLG_MSG_ALL mode:

PushButton, CheckBox, RadioButtonComboBoxListBox 

Windows messages, which remain unhandled by built-in InstallScript functions, can be intercepted in two ways. The first method consists in catching BN_CLICKED or EN_CHANGE notification by using a regular built-in InstallScript mechanism of WaitOnDialog and after that in going manually over a message loop by PeekMessage/GetMessage functions without leaving the WaitOnDialog switch/case block. The second method is more sophisticated and more reliable as well - this is the windows subclassing method. We will show how to use it in the last chapter.

Modal Dialog with Progress Bar

Let’s look over our first basic example. There we create a modal dialog which works like an InstallShield SdShowMsg function with an addition of a progress bar and a status message.

First of all, you have to create a new dialog of a MessageBox size with ProgressBar and StaticText controls to show status messages.

Our dialog definition in a resource file will look like a definition for an SdShowMsg dialog.

  1. Create an empty dialog and resize it to a MessageBox dialog size
  2. Set its Resource Identifier = 20009
  3. Set its style Modal = TRUE
  4. Set its Other Windows Styles as shown here:


  5. Create StaticText control
  6. Set its Control Identifier = 1303
  7. Set its stiles to:
    1. No Prefix = TRUE
    2. No Text Wrap = TRUE
    3. Transparent = FALSE
  8. Create ProgressBar control
  9. Set its Control Identifier = 1301

Define dialog and control IDs in an InstallScript header file:

#define CTRL_PROGRESS	1301
#define CTRL_STATIC	1303
#define DLG_ID		20009

Define progress bar message codes (WM_USER is already defined by InstallShield) and Win32 API functions:

#define PBM_SETPOS		(WM_USER+2)
#define PBM_STEPIT		(WM_USER+5)
#define PBM_SETRANGE32	(WM_USER+6)

prototype User32.UpdateWindow(HWND);

This is a ShowProgressDialog’s main function. The dialog is created by executing this function with bShow=TRUE. When the function is called a second time with the same dialog name and bShow=FALSE, the dialog destructs.
The progress bar has tickles ranged from 0 to 100 but this setting can be changed by your wish.

prototype number ShowProgressDialog(string, string, BOOL);
function number  ShowProgressDialog(szDlg, szTitle, bShow)
	number nResult;
	HWND hwndDlg,hCtrl;
	if(bShow) then
    		if(EzDefineDialog( szDlg, "", "", DLG_ID ) = DLG_ERR) then
        			return -1;

		nResult = WaitOnDialog(szDlg);

		// wait until Error or DLG_INIT message
		while(nResult !=DLG_INIT && nResult >= 0)
			nResult = WaitOnDialog(szDlg);
		hwndDlg = CmdGetHwndDlg(szDlg);
		SdSetDlgTitle(szDlg, hwndDlg, szTitle);

		//initialize progress bar control
		hCtrl = GetDlgItem(hwndDlg, CTRL_PROGRESS);
	    	nResult = SendMessage(hCtrl, PBM_SETRANGE32, 0, 100);
	    	nResult = SendMessage(hCtrl, PBM_SETSTEP, 10, 0);

	    	ShowWindow(hwndDlg, SW_SHOW);

	return 0;

Each time we want to increment the progress bar, we run the function IncrementProgressDialog.
The progress bar can be updated by sending one of the two messages, PBM_STEPIT or PBM_SETPOS.
If we want to set a tickle number directly, there should be sent a PBM_SETPOS message with a wParam equal to a tickle number:

SendMessage(hDlg, PBM_SETPOS, nIndex, 0);
prototype number IncrementProgressDialog(string, string);
function number IncrementProgressDialog (szDlg , szMsg)
	HWND hDlgCtrl;
	hDlgCtrl = GetDlgItem(CmdGetHwndDlg(szDlg), CTRL_PROGRESS);
	CtrlSetText(szDlg, CTRL_STATIC, szMsg);
	return SendMessage(hDlgCtrl, PBM_STEPIT, 0, 0);

This script shows how the Progress dialog actually works:

szDlg = "ShowDialog";
szTitle = "Status dialog with progress bar";
if(ShowProgressDialog(szDlg,szTitle,TRUE)) then
	return -1;
//do some action//increment progress bar and update status message
IncrementProgressDialog(szDlg,"< progress bar status message >");
//do some action//increment progress bar and update status message
IncrementProgressDialog(szDlg, "<progress />");

ListBox Control

If we try to create a standard ListBox control by an InstallShield wizard, we won’t see the LBS_NOSEL style in the “Other Windows Styles” field. An InstallShield team probably thought of style to be excessive and didn’t include it in a styles list. This style could be helpful if we want to create a read-only list box which only shows the information like a multiline read-only EditBox but with white background color instead of a grey one.

Let’s first define windows API functions and message codes:

prototype HWND User32.CreateWindowExA(int, byref string, byref string, 
			int, int, int, int, int, HWND, HWND, HWND, pointer);
prototype BOOL User32.DestroyWindow(HWND);

#define LBS_NOSEL 		0x4000L
#define LBS_NOTIFY		0x0001L
#define LBS_SORT		0x0002L
#define WS_VSCROLL 	0x00200000L

This function creates a custom ListBox control. It must be called from the DLG_INIT section.

prototype HWND CreateListBoxControl(HWND, int, int, int, int);
function HWND CreateListBoxControl (hwndDlg, nLeft, nTop, nWidth, nHeight)
	HWND hwndLB;
	hwndLB = User32.CreateWindowExA (0,
		nLeft, nTop, nWidth, nHeight, hwndDlg, NULL, NULL, NULL);

	ShowWindow (hwndLB, SW_SHOW);

	return hwndLB;

This is a complete DLG_INIT section:

case DLG_INIT:
	//create custom ListBox control
	hwndLB = CreateListBoxControl (hwndDlg, 170,50,200,80);

	//add text lines to ListBox
	szText = "First line";
	SendMessage(hwndLB, LB_ADDSTRING, 0, &szText);
	szText = "Second line";
	SendMessage(hwndLB, LB_ADDSTRING, 0, &szText);
	szText = "Third line";
	SendMessage(hwndLB, LB_ADDSTRING, 0, &szText);

Before destroying the dialog, we must manually destroy the ListBox window first:


IPAddress Control

This example shows how to use the standard windows IPAddress control.
The IPAddress control is not included in InstallShield toolbar view, so it should be created manually with the CreateWindowExA function.

First let’s define missing definitions of message codes and functions:

prototype HWND User32.CreateWindowExA(int, byref string, byref string, 
			int, int, int, int, int, HWND, HWND, HWND, pointer);
prototype BOOL User32.DestroyWindow(HWND);

#define WS_EX_LEFT		0x00000000L
#define WS_EX_LTRREADING	0x00000000L
#define WS_EX_CLIENTEDGE	0x00000200L

#define WC_IPADDRESSA	"SysIPAddress32"


This function is used in the DLG_INIT section. It creates a dialog child window from a SysIPAddress32 windows class and initializes it with a given IP address string.

prototype HWND CreateIPAddressControl(HWND, int, int, int, int, string);
function HWND CreateIPAddressControl (hwndDlg, nLeft, nTop, nWidth, nHeight, szIP)
	HWND hIPControl;
	LIST list;
string	sz1,sz2,sz3,sz4;
 	number n1,n2,n3,n4,nIP;
	hIPControl = User32.CreateWindowExA 
		nLeft, nTop, nWidth, nHeight, hwndDlg, NULL, NULL, NULL);

	if(hIPControl=NULL) then
		return 0;

	list = ListCreate(STRINGLIST);

	nIP = (n1<<24) + (n2<<16) + (n3<<8) + n4;


	return hIPControl;

This function receives an IPAddress control handler and returns the resulting IP address string.

prototype string GetIPAddress(HWND);
function string GetIPAddress(hIPControl)
string	sz1,sz2,sz3,sz4, szIP;
 	number n1,n2,n3,n4,nIP;
    	n1 = (nIP>>24) & 0xff;
    	n2 = (nIP>>16) & 0xff;
    	n3 = (nIP>>8) & 0xff;
    	n4 = nIP & 0xff;

	szIP = sz1+"."+sz2+"."+sz3+"."+sz4;

	return szIP;

Here, we combine these functions together in an InstallScript environment:

case DLG_INIT:
	//create and initialize IP address window
	hIPControl  = CreateIPAddressControl(hwndDlg, 34,123,160,21,"");

case NEXT:
    	//retrieve entered IP address
	szIP = GetIPAddress(hIPControl);

Before destroying the dialog manually, we need to destroy the IP address window:

User32.DestroyWindow(hIPControl );

ListView Control in Grid Mode

InstallShield doesn’t have a built in grid control so, in this case, we can use a ListView control in a LVS_REPORT mode for showing a grid table.

Create a ListView control and set its window styles in a control wizard.
All styles except LVS_REPORT are not mandatory and are selected here for convenience.


ListBox styleStyle description
LVS_SHOWSELALWAYSA selection, if any, is always shown, even if a control does not have a focus.
LVS_SORTASCENDINGItem indexes are sorted based on an item text in an ascending order.
LVS_EDITLABELSAn Item text can be edited in place.
LVS_NOSORTHEADERColumn headers do not work like buttons. When this style is used in a report view, clicking a column header does not carry out an action such as sorting.
LVS_SINGLESELOnly one item at a time can be selected. By default, multiple items may be selected.

Define message codes which are not defined yet:

#define LVM_SETIMAGELIST       	(LVM_FIRST + 3)

#define LVS_EX_FULLROWSELECT	0x00000020
#define LVS_EX_SUBITEMIMAGES    	0x00000002
#define LVS_EX_GRIDLINES        	0x00000001
#define LVS_EX_HEADERDRAGDROP   	0x00000010

#define LR_LOADFROMFILE    		0x00000010

#define LVIF_IMAGE              	0x0002
#define LVIF_STATE              	0x0008

#define ILC_COLOR4              	0x0004

#define IMAGE_ICON         		1
#define LVSIL_SMALL           	1

prototype HWND User32.LoadImage(pointer,pointer,int,int,int,int);
prototype HWND comctl32.ImageList_Create(int,int,int,int,int);
prototype int comctl32.ImageList_ReplaceIcon(HWND,int,HWND);

Define a PSTR structure to reinitialize pointers, like "ptr=&val; val=*ptr" in C/C++:

typedef PSTR
	string str[MAX_PATH];

Here we add a new column to our grid:

prototype number ListViewAddColumn(HWND, number, number, string);
function number ListViewAddColumn(hListWnd, nColID, nColSize, szColName)
	lvc.fmt 		= LVCFMT_LEFT;
    	lvc.iSubItem   	= nColID;         	= nColSize;
	lvc.pszText    	= &szColName;

    	return SendMessage(hListWnd, LVM_INSERTCOLUMN, nColID, &lvc);

Here, we add a new line to our grid. Then, at first main column, we set a text, draw an icon and, finally receive an item’s line number.
Text strings in the main items column should be unique. All newly added lines are automatically sorted so, if we want to know a line’s real number, we need to use the return value from this function.

prototype number ListViewAddItem(HWND, number, number,string);
function number ListViewAddItem(hListWnd, nItemID, nImageID, szItemName)
	LVITEM lvit;
	lvit.mask 	= LVIF_TEXT|LVIF_IMAGE;
	lvit.iItem 	= nItemID;
	lvit.iImage 	= nImageID;
	lvit.iSubItem 	= 0;
	lvit.pszText 	= &szItemName;

	return SendMessage(hListWnd, LVM_INSERTITEM, 0, &lvit);

Here, we set a text for secondary columns.
To place a text, we need to specify a main item’s line number and a column number of our subitem.

prototype number ListViewAddSubItem(HWND, number, number, string);
function number ListViewAddSubItem(hListWnd, nItemID, nSubItemID, szSubItemName)
	LVITEM lvit;
	lvit.mask = LVIF_TEXT;
	lvit.iItem = nItemID;
	lvit.iSubItem = nSubItemID;
	lvit.pszText = &szSubItemName;

	return SendMessage(hListWnd, LVM_SETITEM, 0, &lvit);

Here, we retrieve a main item’s text for the selected line.

prototype number ListViewGetSelectedItemText(HWND, byref string);
function number ListViewGetSelectedItemText(hListWnd, szItemName)
	 string szListText[MAX_PATH];
	 LVITEM lvit;
	 number ret;
	 PSTR pointer pstr;
	ret = SendMessage(hListWnd, LVM_GETNEXTITEM, -1, LVIS_SELECTED);
	if(ret > -1) then
		lvit.mask 	= LVIF_TEXT;
		lvit.iItem 	= ret;
		lvit.iSubItem 	= 0;
		lvit.pszText    	= &szListText;
		lvit.cchTextMax	= MAX_PATH;

		SendMessage(hListWnd, LVM_GETITEMTEXT, ret, &lvit);
		pstr = lvit.pszText;

		szItemName 	= pstr->str;
		return ret;
		szItemName 	= "";
		return -1;

Create columns and add lines for the ListView control.
Here, we use one icon for the first 10 lines and another icon for the remaining lines.

prototype number ListViewInitialize(HWND);
function number ListViewInitialize(hwndList)
	number ret, nIdx;
	string szIdx;
//LVS_EX_FULLROWSELECT  - When an item is selected, the item and 
//all its subitems are highlighted.
//LVS_EX_GRIDLINES - Displays gridlines around items and subitems.
//LVS_EX_HEADERDRAGDROP - Enables drag-and-drop reordering of columns 
//in a list-view control.
//LVS_EX_SUBITEMIMAGES - Allows images to be displayed for subitems.


	SendMessage (hwndList, LVM_DELETEALLITEMS, 0, 0);

	ret = ListViewAddColumn (hwndList,0,80,"Main Column");
	ret = ListViewAddColumn (hwndList,1,80,"Sec Column #1");
	ret = ListViewAddColumn (hwndList,2,80,"Sec Column #2");

	for nIdx = 0 to 19
		if (nIdx < 10) then
			ret = ListViewAddItem(hwndList,0,0,"Key #"+szIdx);
			ret = ListViewAddItem(hwndList,0,1,"Key #"+szIdx);
		ListViewAddSubItem(hwndList,ret,1,"Value1 #"+szIdx);
		ListViewAddSubItem(hwndList,ret,2,"Value2 #"+szIdx);

	return 0;

Here, we create and initialize an image list and load there 2 icons.

prototype number ListViewCreateImageList(HWND,string,string);
function number ListViewCreateImageList (hwndList, szImageFile1, szImageFile2)
HWND img1,img2,himl;
	img1 = LoadImage(NULL,&szImageFile1,IMAGE_ICON,16,16,LR_LOADFROMFILE);
	img2 = LoadImage(NULL,& szImageFile2,IMAGE_ICON,16,16,LR_LOADFROMFILE);

	himl = ImageList_Create(16,16,ILC_COLOR4,2,0);
	ImageList_ReplaceIcon(himl, -1, img1);
	ImageList_ReplaceIcon(himl, -1, img2);

	return SendMessage(hwndList, LVM_SETIMAGELIST, LVSIL_SMALL, himl);

This example shows how to use the code below:

case INIT_DLG:
	hwndList = GetDlgItem(hwndDlg,nListID);

case NEXT:
	ret = ListViewGetSelectedItemText(hwndList,szListText);
	if(ret < 0) then
		//no row is selected
		//print szListText

Balloon Tips

The following example shows how to use _ pop-up balloon tips in Edit controls.
Balloon tips may contain a title, message and icon (information, warning, etc…).
In order to use this API functionality, you must have Comclt32.dll of version 6.0 from the latest Microsoft SDK.

This is a definition part.

#define EM_SHOWBALLOONTIP		0x1503
#define EM_HIDEBALLOONTIP		0x1504
#define TTI_NONE                	0
#define TTI_INFO                	1
#define CP_ACP                   	0       		// default to ANSI code page
#define MB_PRECOMPOSED 		0x00000001  	// use precomposed chars

    number cbStruct;
    number pszTitle;
    number pszText;
    number ttiIcon;

Here, we receive a title and message strings, translate them to Unicode and send as a message to an Edit control. The EM_SHOWBALLOONTIP message makes balloon tip to be shown.

prototype number ShowBalloonTip(HWND,string,string);
function number ShowBalloonTip(hWndCtrl, szTitle, szMsg)
    	string szBalTitleBuf[MAX_PATH], szBalTextBuf[MAX_PATH];
    	pointer pBalTitleBuf, pBalTextBuf;
	pBalTextBuf = &szBalTextBuf;
	pBalTitleBuf = &szBalTitleBuf;

	MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,&szMsg, 
			StrLengthChars(szMsg)+1, pBalTextBuf, MAX_PATH);
	MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,&szTitle, 
			StrLengthChars(szTitle)+1, pBalTitleBuf, MAX_PATH);

	baloon.cbStruct = SizeOf(baloon);
	baloon.pszText = pBalTextBuf;
	baloon.pszTitle = pBalTitleBuf;
	baloon.ttiIcon = TTI_INFO;

	return SendMessage(hWndCtrl,EM_SHOWBALLOONTIP,0,&baloon);

This function closes the previously shown balloon tip. It may also be closed by simply clicking on it.

prototype number HideBalloonTip(HWND);
function number HideBalloonTip(hWndCtrl)
	return SendMessage(hWndCtrl, EM_HIDEBALLOONTIP, 0, 0);

Custom Event Handling

In the previous chapters, we obtained all missed InstallScript functionality by simply sending windows messages. The receiving of windows messages is a bit more complex task. We are going to solve it by using a windows subclassing mechanism. InstallScript unfortunately doesn’t support function pointers, so we will write the entire message handling code in an external C/C++ DLL and afterwards replace an InstallScript native windows message handling procedure with our C/C++ function.

In our C/C++ code in the first switch/case block, we catch WM_CTLCOLORSTATIC event in order to color read-only edit box to the white color.
In second and third blocks, we try to catch the WM_HELP and WM_SETFOCUS messages for the Edit box and send them back to the InstallScript. Thus we notify the InstallScript control that some action is being happening right now. It will make him to send its own notification back to the WaitOnDialog function.
This trick allows us to run the ShowBalloonTip function from the InstallScript.

Set the DS_CONTEXTHELP style in a dialog styles wizard in order to use the WM_HELP feature.
The following C/C++ code should be compiled to a simple C/C++ DLL without ATL and MFC libraries.

// subclass.cpp : Defines the exported functions for the DLL application.

#include "stdafx.h"
#include <stdio.h>

#include <process.h>
static WNDPROC oldstaticproc;
static int nCtrlID;

long __stdcall StaticProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
		if(GetDlgCtrlID((HWND)lParam) == nCtrlID)
			//SetBkMode((HDC)wParam, TRANSPARENT);
			SetBkMode((HDC)wParam, OPAQUE);
			return (INT_PTR)(HBRUSH)GetStockObject(DC_BRUSH);

		if(LOWORD(wParam) == nCtrlID)
			if(HIWORD(wParam) == EN_SETFOCUS)
					(nCtrlID, EN_CHANGE),
					(LPARAM)GetDlgItem(hwnd, nCtrlID));
			else if(HIWORD(wParam) == EN_KILLFOCUS)
				SendMessage(GetDlgItem(hwnd, nCtrlID),

	case WM_HELP:
		if(wParam == 0 && lphlp != 0)
			if(GetDlgCtrlID((HWND)lphlp->hItemHandle) == nCtrlID)
					(LPARAM)GetDlgItem(hwnd, nCtrlID));
	return CallWindowProc(oldstaticproc, hwnd, msg, wParam, lParam);

extern "C" __declspec(dllexport) void SubClassWindowProc(HWND hWnd,int argCtrlID)
	oldstaticproc = (WNDPROC)SetWindowLong(hWnd, GWL_WNDPROC, (LONG)StaticProc);
	nCtrlID = argCtrlID;

This is a prototype definition for an exported DLL method. It should be placed before the WaitOnDialog code block. Pay attention to the “cdecl” parameter.

prototype cdecl subclass.SubClassWindowProc(HWND,int);

Here, we replace the original InstallScript windows messaging procedure with our custom C/C++ function at the initialization time and execute ShowBalloonTip when the Edit control receives focus or when a user clicks on the Edit control with a question mark.

nID = WaitOnDialog(szDlg);

	case INIT_DLG:
		hwndDlg = CmdGetHwndDlg( szDlg );
		hwndEdit = GetDlgItem(hwndDlg,1303);

	case 1303:
		ShowBalloonTip(hwndEdit,"EditBox Title","Tool tip help message");



The following code samples contain all the features discussed in the above chapters:


  • 28th February, 2011: Initial post
  • 30th April, 2011: Article updated


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Mark Babayev
Software Developer (Senior)
Israel Israel
Working with .NET since 2005
Expertise in developing tools and services for SharePoint, TFS, BI/SSRS
Technical partner in start-up developing Outlook Add-ins.
Owning CodePlex projects:

You may also be interested in...


Comments and Discussions

QuestionHow should I implement Balloon Tip for an edit control in an InstallScript MSI project in INSTALLSHIELD 2015 Pin
Member 128415899-Nov-16 5:52
memberMember 128415899-Nov-16 5:52 
QuestionLoadImage return 0 as handle Pin
RockT16-Jul-13 23:57
memberRockT16-Jul-13 23:57 
AnswerRe: LoadImage return 0 as handle Pin
Mark Babayev27-Jul-13 4:00
professionalMark Babayev27-Jul-13 4:00 
GeneralRe: LoadImage return 0 as handle Pin
RockT28-Jul-13 14:40
memberRockT28-Jul-13 14:40 
QuestionStop button Pin
Lucaxyz227-Feb-13 21:37
memberLucaxyz227-Feb-13 21:37 
AnswerRe: Stop button Pin
Mark Babayev28-Feb-13 22:49
memberMark Babayev28-Feb-13 22:49 
GeneralRe: Stop button Pin
Lucaxyz21-Mar-13 4:36
memberLucaxyz21-Mar-13 4:36 
GeneralRe: Stop button Pin
RockT18-Jul-13 14:18
memberRockT18-Jul-13 14:18 
GeneralRe: Stop button Pin
Mark Babayev27-Jul-13 3:51
professionalMark Babayev27-Jul-13 3:51 
QuestionNot working with skinable dialog Pin
Member 299407223-Jun-12 4:15
memberMember 299407223-Jun-12 4:15 
AnswerRe: Not working with skinable dialog Pin
Mark Eisenstein21-Jul-12 4:49
memberMark Eisenstein21-Jul-12 4:49 
GeneralRe: Not working with skinable dialog Pin
Wes Aday23-Jun-14 10:31
memberWes Aday23-Jun-14 10:31 
QuestionHow to associate progress bar with setup progress in installscript MSI project? Pin
wang8692432418-Jul-11 17:42
memberwang8692432418-Jul-11 17:42 
AnswerRe: How to associate progress bar with setup progress in installscript MSI project? Pin
Mark Eisenstein20-Jul-11 9:19
memberMark Eisenstein20-Jul-11 9:19 
AnswerRe: How to associate progress bar with setup progress in installscript MSI project? Pin
Mark Eisenstein20-Jul-11 9:44
memberMark Eisenstein20-Jul-11 9:44 
GeneralVery nice tutorial Pin
tigrouu14-Apr-11 11:04
membertigrouu14-Apr-11 11:04 
GeneralMy vote of 5 Pin
KentuckyEnglishman8-Mar-11 2:36
memberKentuckyEnglishman8-Mar-11 2:36 
GeneralISScript = Painful Pin
TopazJester7-Mar-11 22:03
memberTopazJester7-Mar-11 22:03 
GeneralBasic Info Missing Pin
sam.hill28-Feb-11 5:47
membersam.hill28-Feb-11 5:47 
AnswerRe: Basic Info Missing [modified] Pin
Mark Eisenstein8-Mar-11 2:46
memberMark Eisenstein8-Mar-11 2:46 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web02-2016 | 2.8.180615.1 | Last Updated 1 May 2011
Article Copyright 2011 by Mark Babayev
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid