source - Página personalizada para el número de serie en Inno Setup
open source installer (3)
La forma más sencilla de agregar un cuadro de clave de serie, debajo de los campos de texto Nombre y Organización, es agregar algo como lo siguiente a su archivo iss.
[Code]
function CheckSerial(Serial: String): Boolean;
begin
// serial format is XXXX-XXXX-XXXX-XXXX
Serial := Trim(Serial);
if Length(Serial) = 19 then
result := true;
end;
Esto se puede combinar útilmente con
[Setup]
DefaultUserInfoSerial={param:Serial}
que completará la serie si previamente ingresó para la instalación.
¿Cómo crear CustomPage en Inno Setup con cuadros de edición para el número de serie? Por ejemplo, 6x5chars o 7x5chars?
La secuencia de comandos debe verificar si todas las casillas están llenas antes de que el botón Siguiente esté disponible.
También sería bueno si pudiera implementarse la función Copiar / Pegar que permitiera llenar todos los cuadros de edición si el contenido del portapapeles coincide con el patrón del número de serie.
Puede hacer que Inno solicite al usuario una clave de serie agregando una función de evento CheckSerial()
.
Si desea tener más control sobre la página, puede usar una de las páginas de stock ( CreateInput...Page
) o una página personalizada en el asistente de configuración usando CreateCustomPage()
y agregando los controles que necesite.
Vea el ejemplo de codedlg.iss incluido con la configuración de Inno.
Este es un enfoque que utiliza la página personalizada donde se crean los cuadros de edición separados. Solo necesita especificar el valor para la constante SC_EDITCOUNT
donde se define el número de cuadros de edición y SC_CHARCOUNT
cuál es el número de caracteres que se pueden ingresar en estos cuadros de edición. Si se encuentra en el primer cuadro de edición, puede pegar el número de serie completo si está en el formato del patrón delimitado por el carácter -
(la función TryPasteSerialNumber
aquí). Para obtener el número de serie de los cuadros de edición, es suficiente llamar a GetSerialNumber
donde puede especificar también un delimitador para el formato de salida (si es necesario).
[Setup]
AppName=Serial number project
AppVersion=1.0
DefaultDirName={pf}/Serial number project
[code]
function SetFocus(hWnd: HWND): HWND;
external ''[email protected] stdcall'';
function OpenClipboard(hWndNewOwner: HWND): BOOL;
external ''[email protected] stdcall'';
function GetClipboardData(uFormat: UINT): THandle;
external ''[email protected] stdcall'';
function CloseClipboard: BOOL;
external ''[email protected] stdcall'';
function GlobalLock(hMem: THandle): PAnsiChar;
external ''[email protected] stdcall'';
function GlobalUnlock(hMem: THandle): BOOL;
external ''[email protected] stdcall'';
var
SerialPage: TWizardPage;
SerialEdits: array of TEdit;
const
CF_TEXT = 1;
VK_BACK = 8;
SC_EDITCOUNT = 6;
SC_CHARCOUNT = 5;
SC_DELIMITER = ''-'';
function IsValidInput: Boolean;
var
I: Integer;
begin
Result := True;
for I := 0 to GetArrayLength(SerialEdits) - 1 do
if Length(SerialEdits[I].Text) < SC_CHARCOUNT then
begin
Result := False;
Break;
end;
end;
function GetClipboardText: string;
var
Data: THandle;
begin
Result := '''';
if OpenClipboard(0) then
try
Data := GetClipboardData(CF_TEXT);
if Data <> 0 then
Result := String(GlobalLock(Data));
finally
if Data <> 0 then
GlobalUnlock(Data);
CloseClipboard;
end;
end;
function GetSerialNumber(ADelimiter: Char): string;
var
I: Integer;
begin
Result := '''';
for I := 0 to GetArrayLength(SerialEdits) - 1 do
Result := Result + SerialEdits[I].Text + ADelimiter;
Delete(Result, Length(Result), 1);
end;
function TrySetSerialNumber(const ASerialNumber: string; ADelimiter: Char): Boolean;
var
I: Integer;
J: Integer;
begin
Result := False;
if Length(ASerialNumber) = ((SC_EDITCOUNT * SC_CHARCOUNT) + (SC_EDITCOUNT - 1)) then
begin
for I := 1 to SC_EDITCOUNT - 1 do
if ASerialNumber[(I * SC_CHARCOUNT) + I] <> ADelimiter then
Exit;
for I := 0 to GetArrayLength(SerialEdits) - 1 do
begin
J := (I * SC_CHARCOUNT) + I + 1;
SerialEdits[I].Text := Copy(ASerialNumber, J, SC_CHARCOUNT);
end;
Result := True;
end;
end;
function TryPasteSerialNumber: Boolean;
begin
Result := TrySetSerialNumber(GetClipboardText, SC_DELIMITER);
end;
procedure OnSerialEditChange(Sender: TObject);
begin
WizardForm.NextButton.Enabled := IsValidInput;
end;
procedure OnSerialEditKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
var
Edit: TEdit;
EditIndex: Integer;
begin
Edit := TEdit(Sender);
EditIndex := Edit.TabOrder - SerialEdits[0].TabOrder;
if (EditIndex = 0) and (Key = Ord(''V'')) and (Shift = [ssCtrl]) then
begin
if TryPasteSerialNumber then
Key := 0;
end
else
if (Key >= 32) and (Key <= 255) then
begin
if Length(Edit.Text) = SC_CHARCOUNT - 1 then
begin
if EditIndex < GetArrayLength(SerialEdits) - 1 then
SetFocus(SerialEdits[EditIndex + 1].Handle)
else
SetFocus(WizardForm.NextButton.Handle);
end;
end
else
if Key = VK_BACK then
if (EditIndex > 0) and (Edit.Text = '''') and (Edit.SelStart = 0) then
SetFocus(SerialEdits[EditIndex - 1].Handle);
end;
procedure CreateSerialNumberPage;
var
I: Integer;
Edit: TEdit;
DescLabel: TLabel;
EditWidth: Integer;
begin
SerialPage := CreateCustomPage(wpWelcome, ''Serial number validation'',
''Enter the valid serial number'');
DescLabel := TLabel.Create(SerialPage);
DescLabel.Top := 16;
DescLabel.Left := 0;
DescLabel.Parent := SerialPage.Surface;
DescLabel.Caption := ''Enter valid serial number and continue the installation...'';
DescLabel.Font.Style := [fsBold];
SetArrayLength(SerialEdits, SC_EDITCOUNT);
EditWidth := (SerialPage.SurfaceWidth - ((SC_EDITCOUNT - 1) * 8)) div SC_EDITCOUNT;
for I := 0 to SC_EDITCOUNT - 1 do
begin
Edit := TEdit.Create(SerialPage);
Edit.Top := 40;
Edit.Left := I * (EditWidth + 8);
Edit.Width := EditWidth;
Edit.CharCase := ecUpperCase;
Edit.MaxLength := SC_CHARCOUNT;
Edit.Parent := SerialPage.Surface;
Edit.OnChange := @OnSerialEditChange;
Edit.OnKeyDown := @OnSerialEditKeyDown;
SerialEdits[I] := Edit;
end;
end;
procedure CurPageChanged(CurPageID: Integer);
begin
if CurPageID = SerialPage.ID then
WizardForm.NextButton.Enabled := IsValidInput;
end;
procedure InitializeWizard;
begin
CreateSerialNumberPage;
end;
Y aquí es cómo se ve: