How to resize the uninstall's WizardSmallBitmapImage to these dimensions?
Left := ScaleX(0);
Width := ScaleX(500);
Height := ScaleY(60);
Set this in the InitializeUninstallProgressForm event function.
procedure InitializeUninstallProgressForm();
begin
with UninstallProgressForm do
begin
WizardSmallBitmapImage.Left := ScaleX(0);
WizardSmallBitmapImage.Width := MainPanel.Width;
WizardSmallBitmapImage.Height := MainPanel.Height;
PageDescriptionLabel.Visible := False;
PageNameLabel.Visible := False;
end;
end;
Related
I'm having trouble getting the queue in my program to work. Every adjustment I've tried has resulted in an 'ERangeError: Range check error'.
I know this is because the program is trying to access something that doesn't exist, but I cannot figure out how to fix it.
Here is my queue implementation...
node = record //Square on chessboard
x: integer; //Row coordinate
y: integer; //Col coordinate
d: integer; //Distance from starting position
next: ^node;// (for the queue)
end; //node
coord = ^node;//'Coordinates'
queue = record//Queue w/ Linked List
head: coord;
tail: coord;
end; //queue
procedure init(var q: queue);
begin
q.head := nil;
q.tail := nil;
end; //init
function isEmpty(const q: queue): boolean;
begin
isEmpty := (q.head = nil);
end; //isEmpty
procedure push(var q: queue; m, n, o: integer);
var C: coord;
begin
new(C);
C^.x := m;
C^.y := n;
C^.d := o;
if q.head = nil then begin
q.head := C;
q.tail := q.head;
end
else begin
q.tail^.next := C;
q.tail := C;
end;
end; //push
procedure pop(var q: queue; out m: int; out n: int; out o: int);
var C: coord;
begin
m := q.head^.x;
n := q.head^.y;
o := q.head^.d;
C := q.head;
q.head := q.head^.next;
dispose(C);
if q.head = nil then q.tail := nil;
end; //pop
...and here is the main part of the function that is interacting with it.
while not isEmpty(q) do begin
pop(q, row, col, dst);
new(crd2);
crd2^.x := row;
crd2^.y := col;
crd2^.d := dst;
if valid(B, crd2) and not visited[crd2^.x, crd2^.y] then
visited[crd2^.x, crd2^.y] := true; //Mark square as visited
if (crd2^.x = Gl^.x) and (crd2^.y = Gl^.y) then
exit(crd2^.d); //Goal Check
for i := 1 to 8 do begin
crd2^.x := crd2^.x + mvmtX[i];
crd2^.y := crd2^.y + mvmtY[i];
if valid(B, crd2) and not visited[crd2^.x, crd2^.y] then begin
crd2^.d := crd2^.d + 1;
push(q, crd2^.x, crd2^.y, crd2^.d);
end;//if valid(B, crd)...
end;//for i
end;//while not isEmpty(q)
exit(crd^.d);
end;
I thought I had covered the issue by adding enough new(node) calls in the program, but the error still persists. I'm really at a loss and would appreciate any clarity you could offer.
I would email my professor but he is skiing right now and is hard to reach.
Thank you for any advice :)
Folks!
Does somebody know an Oracle built-in datatypes system dictionary view?
Example:
SELECT DUMP ('HASAN') FROM DUAL;
returns
Typ=96 Len=5: 72,65,83,65,78
Oracle documentation says that it is CHAR or NCHAR datatype.
But is there a view, where I can find this datatype by code returned (Typ=96)?
Does it exist at all?
SELECT t.typecode, name
FROM sys.type$ t, sys.obj$ o
WHERE t.toid = o.oid$ and t.typecode = 96;
You can also check source code of DBMS_TYPES package
select TEXT
from dba_source
where name = 'DBMS_TYPES'
and regexp_like(text, 'TYPECODE');
TYPECODE_DATE PLS_INTEGER := 12;
TYPECODE_NUMBER PLS_INTEGER := 2;
TYPECODE_RAW PLS_INTEGER := 95;
TYPECODE_CHAR PLS_INTEGER := 96;
TYPECODE_VARCHAR2 PLS_INTEGER := 9;
TYPECODE_VARCHAR PLS_INTEGER := 1;
TYPECODE_MLSLABEL PLS_INTEGER := 105;
TYPECODE_BLOB PLS_INTEGER := 113;
TYPECODE_BFILE PLS_INTEGER := 114;
TYPECODE_CLOB PLS_INTEGER := 112;
TYPECODE_CFILE PLS_INTEGER := 115;
TYPECODE_TIMESTAMP PLS_INTEGER := 187;
TYPECODE_TIMESTAMP_TZ PLS_INTEGER := 188;
TYPECODE_TIMESTAMP_LTZ PLS_INTEGER := 232;
TYPECODE_INTERVAL_YM PLS_INTEGER := 189;
TYPECODE_INTERVAL_DS PLS_INTEGER := 190;
TYPECODE_REF PLS_INTEGER := 110;
TYPECODE_OBJECT PLS_INTEGER := 108;
TYPECODE_VARRAY PLS_INTEGER := 247; /* COLLECTION TYPE */
TYPECODE_TABLE PLS_INTEGER := 248; /* COLLECTION TYPE */
TYPECODE_NAMEDCOLLECTION PLS_INTEGER := 122;
TYPECODE_OPAQUE PLS_INTEGER := 58; /* OPAQUE TYPE */
TYPECODE_NCHAR PLS_INTEGER := 286;
TYPECODE_NVARCHAR2 PLS_INTEGER := 287;
TYPECODE_NCLOB PLS_INTEGER := 288;
TYPECODE_BFLOAT PLS_INTEGER := 100;
TYPECODE_BDOUBLE PLS_INTEGER := 101;
TYPECODE_UROWID PLS_INTEGER := 104;
Note, numbers in DBMS_TYPES are related to PL/SQL. However, DUMP is a SQL function which you cannot use in PL/SQL. Thus these numbers are slightly different.
There's DBA_TYPEs, which has a predefined column, e.g.:
SELECT * FROM dba_types WHERE predefined = 'YES';
That seems to have a few of the obvious types (e.g. NUMBER, VARCHAR2, etc) in it, but I wouldn't like to say that's exclusive (for example, the ANYDATA datatype has predefined = NO).
Anyway, it ought to give you an idea of where to look, although why you'd want to I'm not sure?
N.B. If you want to see a list of the dictionary tables, you can do:
select * from dictionary;
You can filter as appropriate, if you can't remember the exact table name!
I managed [code] section of my installer in order to run a simple sql script (a select against an existing db/table).
Compiles fine, retrieve correctly sql machine and instance using the right password but whenever running the installer, at a moment the setup aborts providing message "Microsoft OLE DB Provider for SQL Server: Could not find store procedure 'ÿƥS'.
Of course none of those characters were defined in the sql script (SELECT ##SERVERNAME AS SERVERNAME, DB_NAME() AS [DB_NAME], CURRENT_USER AS [CURRENT_USER]).
Here is the [Code] section:
[Code]
const
//some constants definition
var
//some var definition
var
Page: TWizardPage;
// Used to generate error code by sql script errors
procedure ExitProcess(exitCode:integer);
external 'ExitProcess#kernel32.dll stdcall';
// enable/disable child text boxes & functions when text has been entered into Server textbox. Makes no sense to populate child items unless a value exists for server.
Procedure ServerOnChange (Sender: TObject);
begin
//code there
end;
// enable/disable user/pass text boxes depending on selected auth type. A user/pass is only required for SQL Auth
procedure AuthOnChange (Sender: TObject);
begin
//code there
end;
// Enable next button once a database name has been entered.
Procedure DatabaseOnChange (Sender: TObject);
//code there
end;
// Retrieve a list of databases accessible on the server with the credentials specified.
// This list is shown in the database dropdown list
procedure RetrieveDatabaseList(Sender: TObject);
var
ADOCommand: Variant;
ADORecordset: Variant;
ADOConnection: Variant;
begin
lstDatabase.Items.Clear;
try
// create the ADO connection object
ADOConnection := CreateOleObject('ADODB.Connection');
// build a connection string; for more information, search for ADO
// connection string on the Internet
ADOConnection.ConnectionString :=
'Provider=SQLOLEDB;' + // provider
'Data Source=' + txtServer.Text + ';' + // server name
'Application Name=' + '{#SetupSetting("AppName")}' + ' DB List;'
if chkWindowsAuth.Checked then
ADOConnection.ConnectionString := ADOConnection.ConnectionString +
'Integrated Security=SSPI;' // Windows Auth
else
ADOConnection.ConnectionString := ADOConnection.ConnectionString +
'User Id=' + txtUsername.Text + ';' + // user name
'Password=' + txtPassword.Text + ';'; // password
// open the connection by the assigned ConnectionString
ADOConnection.Open;
try
// create the ADO command object
ADOCommand := CreateOleObject('ADODB.Command');
// assign the currently opened connection to ADO command object
ADOCommand.ActiveConnection := ADOConnection;
// assign text of a command to be issued against a provider
ADOCommand.CommandText := 'SELECT name FROM master.dbo.sysdatabases WHERE HAS_DBACCESS(name) = 1 ORDER BY name';
// this property setting means, that you're going to execute the
// CommandText text command; it does the same, like if you would
// use only adCmdText flag in the Execute statement
ADOCommand.CommandType := adCmdText;
// this will execute the command and return dataset
ADORecordset := ADOCommand.Execute;
// get values from a dataset using 0 based indexed field access;
// notice, that you can't directly concatenate constant strings
// with Variant data values
while not ADORecordset.eof do
begin
lstDatabase.Items.Add(ADORecordset.Fields(0));
ADORecordset.MoveNext;
end ;
finally
ADOConnection.Close;
end;
except
MsgBox(GetExceptionMessage, mbError, MB_OK);
end;
end;
// Execute files specified in [files] section (hardcoded) against the user defined server.database
procedure DeploySQL();
var
Myscript: AnsiString;
ADOCommand: Variant;
ADOConnection: Variant;
begin
// extract script
ExtractTemporaryFile('script.sql');
try
// create the ADO connection object
ADOConnection := CreateOleObject('ADODB.Connection');
// build a connection string; for more information, search for ADO
// connection string on the Internet
ADOConnection.ConnectionString :=
'Provider=SQLOLEDB;' + // provider
'Data Source=' + txtServer.Text + ';' + // server name
'Initial Catalog=' + lstDatabase.Text + ';' + // server name
'Application Name=' + '{#SetupSetting("AppName")}' + ' Execute SQL;' ;
if chkWindowsAuth.Checked then
ADOConnection.ConnectionString := ADOConnection.ConnectionString +
'Integrated Security=SSPI;' // Windows Auth
else
ADOConnection.ConnectionString := ADOConnection.ConnectionString +
'User Id=' + txtUsername.Text + ';' + // user name
'Password=' + txtPassword.Text + ';'; // password
// open the connection by the assigned ConnectionString
ADOConnection.Open;
try
// create the ADO command object
ADOCommand := CreateOleObject('ADODB.Command');
// assign the currently opened connection to ADO command object
ADOCommand.ActiveConnection := ADOConnection;
// load a script from file into variable.
if(LoadStringFromFile(ExpandConstant('{app}\script.sql'), Myscript)) then
begin
// assign text of a command to be issued against a provider. Append all 3 because one of the install assembly strings will always be empty.
ADOCommand.CommandText := Myscript;
// this will execute the script; the adCmdText flag here means
// you're going to execute the CommandText text command, while
// the adExecuteNoRecords flag ensures no data row will be get
// from a provider, what should improve performance
ADOCommand.Execute(NULL, NULL, adCmdText or adExecuteNoRecords);
end
else
begin
MsgBox('Installation files missing.', mbError, MB_OK);
ExitProcess(7);
end ;
finally
ADOConnection.Close;
end;
except
MsgBox(GetExceptionMessage, mbError, MB_OK);
ExitProcess(5);
end;
end;
{ CustomForm_NextkButtonClick }
// try to connect to supplied db. Dont need to catch errors/close conn on error because a failed connection is never opened.
function CustomForm_NextButtonClick(Page: TWizardPage): Boolean;
var
ADOConnection: Variant;
begin
//try
// create the ADO connection object
ADOConnection := CreateOleObject('ADODB.Connection');
// build a connection string; for more information, search for ADO
// connection string on the Internet
ADOConnection.ConnectionString :=
'Provider=SQLOLEDB;' + // provider
'Data Source=' + txtServer.Text + ';' + // server name
'Initial Catalog=' + lstDatabase.Text + ';' + // server name
'Application Name=' + '{#SetupSetting("AppName")}' + ' Execute SQL;' ;
if chkWindowsAuth.Checked then
ADOConnection.ConnectionString := ADOConnection.ConnectionString +
'Integrated Security=SSPI;' // Windows Auth
else
ADOConnection.ConnectionString := ADOConnection.ConnectionString +
'User Id=' + txtUsername.Text + ';' + // user name
'Password=' + txtPassword.Text + ';'; // password
// open the connection by the assigned ConnectionString
ADOConnection.Open;
Result := True;
end;
{ CustomForm_CreatePage }
function CustomForm_CreatePage(PreviousPageId: Integer): Integer;
begin
Page := CreateCustomPage(
PreviousPageId,
ExpandConstant('{cm:CustomForm_Caption}'),
ExpandConstant('{cm:CustomForm_Description}')
);
{ lblServer }
lblServer := TLabel.Create(Page);
with lblServer do
begin
Parent := Page.Surface;
Caption := ExpandConstant('{cm:CustomForm_lblServer_Caption0}');
Left := ScaleX(24);
Top := ScaleY(32);
Width := ScaleX(68);
Height := ScaleY(13);
Enabled := True;
end;
{ txtServer }
txtServer := TEdit.Create(Page);
with txtServer do
begin
Parent := Page.Surface;
Left := ScaleX(112);
Top := ScaleY(32);
Width := ScaleX(273);
Height := ScaleY(21);
TabOrder := 1;
Enabled := True;
OnChange := #ServerOnChange;
end;
{ lblAuthType }
lblAuthType := TLabel.Create(Page);
with lblAuthType do
begin
Parent := Page.Surface;
Caption := ExpandConstant('{cm:CustomForm_lblAuthType_Caption0}');
Left := ScaleX(24);
Top := ScaleY(72);
Width := ScaleX(87);
Height := ScaleY(13);
Enabled := False;
end;
{ chkWindowsAuth }
chkWindowsAuth := TRadioButton.Create(Page);
with chkWindowsAuth do
begin
Parent := Page.Surface;
Caption := ExpandConstant('{cm:CustomForm_chkWindowsAuth_Caption0}');
Left := ScaleX(32);
Top := ScaleY(88);
Width := ScaleX(177);
Height := ScaleY(17);
Checked := True;
TabOrder := 2;
TabStop := True;
OnClick := #AuthOnChange;
Enabled := False;
end;
{ chkSQLAuth }
chkSQLAuth := TRadioButton.Create(Page);
with chkSQLAuth do
begin
Parent := Page.Surface;
Caption := ExpandConstant('{cm:CustomForm_chkSQLAuth_Caption0}');
Left := ScaleX(32);
Top := ScaleY(108);
Width := ScaleX(185);
Height := ScaleY(17);
TabOrder := 3;
OnClick := #AuthOnChange;
Enabled := False;
end;
{ lblUser }
lblUser := TLabel.Create(Page);
with lblUser do
begin
Parent := Page.Surface;
Caption := ExpandConstant('{cm:CustomForm_lblUser_Caption0}');
Left := ScaleX(56);
Top := ScaleY(128);
Width := ScaleX(58);
Height := ScaleY(13);
Enabled := False;
end;
{ lblPassword }
lblPassword := TLabel.Create(Page);
with lblPassword do
begin
Parent := Page.Surface;
Caption := ExpandConstant('{cm:CustomForm_lblPassword_Caption0}');
Left := ScaleX(56);
Top := ScaleY(152);
Width := ScaleX(53);
Height := ScaleY(13);
Enabled := False;
end;
{ txtUsername }
txtUsername := TEdit.Create(Page);
with txtUsername do
begin
Parent := Page.Surface;
Left := ScaleX(120);
Top := ScaleY(128);
Width := ScaleX(241);
Height := ScaleY(21);
Enabled := False;
TabOrder := 4;
end;
{ txtPassword }
txtPassword := TPasswordEdit.Create(Page);
with txtPassword do
begin
Parent := Page.Surface;
Left := ScaleX(120);
Top := ScaleY(152);
Width := ScaleX(241);
Height := ScaleY(21);
Enabled := False;
TabOrder := 5;
end;
{ lblDatabase }
lblDatabase := TLabel.Create(Page);
with lblDatabase do
begin
Parent := Page.Surface;
Caption := ExpandConstant('{cm:CustomForm_lblDatabase_Caption0}');
Left := ScaleX(56);
Top := ScaleY(192);
Width := ScaleX(53);
Height := ScaleY(13);
Enabled := False;
end;
{ lstDatabase }
lstDatabase := TComboBox.Create(Page);
with lstDatabase do
begin
Parent := Page.Surface;
Left := ScaleX(120);
Top := ScaleY(192);
Width := ScaleX(145);
Height := ScaleY(21);
Enabled := False;
TabOrder := 6;
OnDropDown:= #RetrieveDatabaseList;
OnChange:= #DatabaseOnChange;
end;
with Page do
begin
OnNextButtonClick := #CustomForm_NextButtonClick;
end;
Result := Page.ID;
end;
procedure CurPageChanged(CurPageID: Integer);
begin
// set initial status of next button. Should be disabled when page is first loaded, but should be enabled if user clicked back.
if CurPageID = Page.ID then
WizardForm.NextButton.Enabled := bIsNextEnabled;
end;
procedure CurStepChanged(CurStep: TSetupStep);
begin
// The preinstall step seems like the best time to do the actual install. The problem is that this is not a traditional install. Nothing is copied to the users' pc
if CurStep = ssInstall then
DeploySQL;
end;
procedure InitializeWizard();
begin
bIsNextEnabled := False;
CustomForm_CreatePage(wpLicense);
end;
Any idea?
thanks
I got the solution!
Problem occurs in the if(LoadStringFromFile(ExpandConstant('{app}\script.sql'), Myscript)) statement because the sql file was not ANSI coded.
Everything gone fine by changing the coding.
thanks everybody!
when add a lot of picture node to the teetree control,and set text offset to 30,then scroll to the end,the last line display picture only.
how should i do?
this is the result of the error:
procedure TForm1.FormCreate(Sender: TObject);
var i:Integer;
imgBox:TImageShape;
curLeft,curTop:Integer; //绘制完成文档视图后当前左上角坐标
begin
curLeft:=-100-15;
curTop:=0;
for i:=0 to 10 do
begin
imgBox := TImageShape.Create(Self);
imgBox.Width := 100;
imgBox.Height := 100;
curLeft := curLeft + 100 + 15 * 2;
if (curLeft + 100 + 15)>= Tree1.Width then
begin
curLeft := 15;
curTop := curTop + 100 + 15 * 2;
end;
imgBox.Left := curLeft;
imgBox.Top := curTop;
imgBox.Font.Style:=[fsBold];
imgBox.Font.Size:=16;
imgBox.Text.VertAlign:=vtaBottom;
imgBox.Text.VertOffset:=30;
imgBox.Text.Add('Node'+inttostr(i));
imgBox.ImageListIndex:=0;
imgBox.Tree:=Tree1;
end;
end;
I've added it to the public tracker here with a possible fix to be further investigated.
I'm looking for a way to create a one page installer in Inno Setup, just look at this screenshot:
Can anyone please give me the codes for doing this?
Or totally I would like to merge pages abilities in Inno Setup. For example merge Select directory page with Components page and etc
It's not easy to do by default. But it can be done, the following code
produced a page like this one.
[Setup]
AppName=Test
AppVersion=1.5
DefaultDirName={code:AppDir}
;Disable all of the default wizard pages
DisableDirPage=yes
DisableProgramGroupPage=yes
DisableReadyMemo=yes
DisableReadyPage=yes
DisableStartupPrompt=yes
DisableWelcomePage=yes
;May want this, after install.
DisableFinishedPage=no
[Messages]
ButtonNext=Install
[Files]
Source:"e:\test.txt"; DestDir: "{app}"
Source:"e:\test.txt"; DestDir: "{app}"; DestName: "test1.txt"; Check: Option1;
Source:"e:\test.txt"; DestDir: "{app}"; DestName: "test2.txt"; Check: Option2;
[Code]
var
MainPage : TWizardPage;
edtFolderToInstall : TEdit;
InstallLocation : String;
Opt1, Opt2 : Boolean;
ChkOption1 : TCheckBox;
ChkOption2 : TCheckBox;
function AppDir(Param: String): String;
begin
// Set Default if not set.
if InstallLocation = '' then
InstallLocation := ExpandConstant('{pf}') + 'test';
result := InstallLocation;
end;
function Option1 : Boolean;
begin
result := Opt1;
end;
function Option2 : Boolean;
begin
result := Opt2;
end;
procedure BrowseClick(Sender : TObject);
var
Dir : String;
begin
Dir := edtFolderToInstall.Text;
if BrowseForFolder('Select Folder',Dir,false) then
edtFolderToInstall.Text := Dir;
end;
procedure InitializeWizard();
var
lblFolderToInstall : TLabel;
btnFolderToInstall : TButton;
begin
MainPage := CreateCustomPage(wpWelcome,'Setup - Test App Name','This will install "Test App Name" to your computer');
lblFolderToInstall := TLabel.Create(MainPage);
lblFolderToInstall.Parent := MainPage.Surface;
lblFolderToInstall.Top := 10;
lblFolderToInstall.Left := 10;
lblFolderToInstall.Caption := 'If you would like to select a different folder, Click Browse.'
edtFolderToInstall := TEdit.Create(MainPage);
edtFolderToInstall.Parent := MainPage.Surface;
edtFolderToInstall.Top := 25;
edtFolderToInstall.Left := 10;
edtFolderToInstall.Width := 250;
edtFolderToInstall.Text := WizardDirValue;
btnFolderToInstall := TButton.Create(MainPage);
btnFolderToInstall.Parent := MainPage.Surface;
btnFolderToInstall.top := 25;
btnFolderToInstall.Left := 275;
btnfolderToInstall.Caption := 'Browse...';
btnFolderToInstall.OnClick := #BrowseClick;
ChkOption1 := TCheckBox.Create(MainForm);
ChkOption1.Parent := MainPage.Surface;
ChkOption1.Top := 50;
ChkOption1.Left := 10;
ChkOption1.Caption := 'Option 1';
ChkOption2 := TCheckBox.Create(MainForm);
ChkOption2.Parent := MainPage.Surface;
ChkOption2.Top := 75;
ChkOption2.Left := 10;
ChkOption2.Caption := 'Option 2';
end;
function NextButtonClick(CurPageID: Integer): Boolean;
begin
result := True;
// Next pressed, better make sure selected items are correct.
if CurPageId = MainPage.ID then
begin
InstallLocation := edtFolderToInstall.Text;
Opt1 := ChkOption1.Checked;
Opt2 := ChkOption2.Checked;
end;
end;
To pull this off, I use {code:AppDir} as the default directory. This tells InnoSetup to use the function AppDir to retrieve the installation directory. I then can set it using my custom dialog.
Instead of using [Components] and/or [Tasks] I have to use Check in the [Files] Section.