如何在Inno Setup的创建CustomPage与编辑框的序列号? 例如6x5chars或7x5chars?CustomPage在Inno Setup的序列号
脚本应该检查是否可用Next按钮之前所有的箱子都装满。
这将是还不错,如果有可能复制/粘贴功能来实现,如果剪贴板内容的序列号模式相匹配,将允许以填补所有的编辑框。
如何在Inno Setup的创建CustomPage与编辑框的序列号? 例如6x5chars或7x5chars?CustomPage在Inno Setup的序列号
脚本应该检查是否可用Next按钮之前所有的箱子都装满。
这将是还不错,如果有可能复制/粘贴功能来实现,如果剪贴板内容的序列号模式相匹配,将允许以填补所有的编辑框。
下面是一个使用在其中创建单独的编辑框自定义页面的一种方法。您只需指定定义编辑框数量的SC_EDITCOUNT
常量的值,并且SC_CHARCOUNT
可以输入到这些编辑框的字符数是多少。如果你在第一个编辑框中,你可以粘贴整个序列号,如果它的格式是由-
char(这里的TryPasteSerialNumber
函数)定界的模式。要从编辑框中获得序列号,只需拨打GetSerialNumber
即可指定输出格式的分隔符(如果需要)。
[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;
这里是它的样子:
您可以通过创新科技添加CheckSerial()
事件功能提示输入序列密钥的用户。
如果您想更多地控制页面,可以使用中的一个库存页面(CreateInput...Page
)或设置向导中的自定义页面,并根据需要添加控件。
参见随创新安装的codedlg.iss例子。
And +1 here here also! :) – kobik
最简单的方式来增加串行钥匙盒,名称和组织文本字段的下方,是添加类似以下内容您的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;
这可以用
[Setup]
DefaultUserInfoSerial={param:Serial}
如果之前的安装进入,这将在串行填被有效地结合起来。
... ['作为迪安娜已经说过]'(http://stackoverflow.com/a/10385420/960757)... – TLama
在哪里添加验证的串行密钥? –
http://stackoverflow.com/questions/11246105/how-can-i-set-the-serial-for-this-serial-form-inno-setup –
谢谢TLama - 第一次测试是积极的。最迟在星期五进行测试后,我会回复最后的评论。 – RobeN
+1!和我的最爱。 – kobik
似乎是PChar导致的问题,因为它会调用未知类型的错误。你能帮忙吗? 我已经改变一点点部,负责下一个按钮激活/非作用状态: '如果长度(SerialEdits [I]。文本)<5 then' 这会导致下一个按钮是无效,直到所有的编辑框充满5个字符。在您的版本中,每个编辑框中的单个字符使下一个按钮处于活动状态 – RobeN