2012-04-30 29 views
17

Làm thế nào để tạo CustomPage trong thiết lập Inno với hộp chỉnh sửa cho số sê-ri? Ví dụ: 6x5chars hoặc 7x5chars?CustomPage cho số sê-ri trong thiết lập Inno

Tập lệnh nên kiểm tra xem tất cả các ô có được điền trước khi nút Tiếp theo có sẵn hay không.

Sẽ rất tốt nếu có thể có chức năng Sao chép/dán được thực hiện để cho phép lấp đầy tất cả các hộp chỉnh sửa nếu nội dung của khay nhớ tạm khớp với mẫu số sê-ri.

Trả lời

33

Dưới đây là một cách tiếp cận sử dụng trang tùy chỉnh nơi tạo các hộp chỉnh sửa riêng biệt. Bạn chỉ cần chỉ định giá trị cho hằng số SC_EDITCOUNT trong đó số hộp chỉnh sửa được xác định và số SC_CHARCOUNT số ký tự có thể được nhập vào các hộp chỉnh sửa này là gì. Nếu bạn đang ở trong hộp chỉnh sửa đầu tiên, bạn có thể dán toàn bộ số sêri nếu nó ở định dạng theo mẫu được giới hạn bởi - char (hàm TryPasteSerialNumber tại đây). Để lấy số sê-ri từ các hộp chỉnh sửa, nó đủ để gọi GetSerialNumber nơi bạn cũng có thể chỉ định một dấu tách cho định dạng đầu ra (nếu cần).

[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; 

Và đây là cách nó trông giống như:

enter image description here

+2

Cảm ơn bạn TLama - kiểm tra đầu tiên là tích cực. Tôi sẽ lấy lại ý kiến ​​cuối cùng của tôi sau khi kiểm tra vào thứ Sáu chậm nhất. – RobeN

+2

+1! và yêu thích của tôi. – kobik

+0

Có vẻ như PChar gây ra sự cố vì nó gọi lỗi của Loại Không xác định. Bạn có thể giúp đỡ về điều đó? Tôi đã thay đổi một phần chút đó là trách nhiệm Nút Tiếp kích hoạt tiểu bang/Unactive: 'nếu Chiều dài (SerialEdits [I] .text) <5 then' Đó gây Nút Tiếp theo là Inactive đến khi tất cả Sửa Boxes là chứa đầy 5 ký tự. Trong phiên bản single char của bạn trong mỗi Edit Box làm cho nút Next hoạt động. – RobeN

7

Bạn có thể làm cho Inno nhắc người dùng nhập khóa nối tiếp bằng cách thêm chức năng sự kiện CheckSerial().

Nếu bạn muốn kiểm soát nhiều hơn trang, bạn có thể sử dụng một trong các trang chứng khoán (CreateInput...Page) hoặc trang tùy chỉnh trong trình hướng dẫn thiết lập bằng cách sử dụng CreateCustomPage() và thêm điều khiển theo yêu cầu.

Xem ví dụ codedlg.iss đi kèm với thiết lập Inno.

+0

Và +1 ở đây cũng! :) – kobik

2

Cách đơn giản nhất để thêm một hộp chìa khóa Serial, bên dưới các lĩnh vực văn bản Tên và Tổ chức, là thêm một cái gì đó như sau để tập tin iss của bạn.

[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; 

này có thể hữu ích kết hợp với

[Setup] 
DefaultUserInfoSerial={param:Serial} 

mà sẽ điền vào các sê-ri nếu trước đó nhập cho quá trình cài đặt.

+0

... ['như Deanna đã nói'] (http://stackoverflow.com/a/10385420/960757) ... – TLama

+0

Nơi để thêm xác thực vào khóa nối tiếp ??? –

+0

http://stackoverflow.com/questions/11246105/how-can-i-set-the-serial-for-this-serial-form-inno-setup –

Các vấn đề liên quan