从Dephi DLL更新Inno Setup进度条

时间:2016-02-08 03:04:42

标签: delphi dll progress-bar inno-setup pascalscript

我需要你的帮助。我正试图从Inno Setup(ANSI)的Delphi 10 Seattle中编写的DLL中调用函数。但我不明白这是什么问题。如果我在Delphi中创建应用程序并从DLL调用此函数,它的工作完美!请参阅代码清单:

Delphi DLL:

import Foundation
import UIKit

class TestView: UIViewController, UITextInputTraits {


    @IBOutlet weak var TestLabel: UILabel!
    @IBOutlet weak var TypingField: UITextField!
    @IBOutlet weak var progressView: UIProgressView!

    var time : Float = 0.0
    var timer: NSTimer!
    var test = 0;
    var progress : Float = 1
    var myMutableString = NSMutableAttributedString()
    var testStringArray = ["abode" , "tutorial" , "completed",
                            "war", "method", "continue",
                            "machine", "texting" , "iterate"]
    var idx = 0;    
    var setProg : Float = 1     

    func textFieldDidChange(textField: UITextField) {

        let s = TypingField.text!

        if(s.characters.last == " "){
            let word = s.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())

            if(!word.isEmpty){
                print(testStringArray[idx])
                if(word == testStringArray[idx]){
                    idx++;
                    TypingField.text = "";
                    TestLabel.text = testStringArray[idx];
                }else{
                    TypingField.text = "";
                }
            }
        }
    }

    func setProgress() {
        setProg -= 0.1
        progressView.progress = setProg  <-- cannot decrement progress bar

    }



    override func viewDidLoad() {
        super.viewDidLoad() 

        TypingField.autocorrectionType = .No
        TypingField.autocapitalizationType = .None 

        timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector:Selector("setProgress"), userInfo: nil, repeats: true)  

        TestLabel.text = testStringArray[idx];

        TypingField.addTarget(self, action: "textFieldDidChange:", forControlEvents: UIControlEvents.EditingChanged)                            
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

Inno Setup(ANSI):

function Process(Pb: TProgressBar): Integer; stdcall;
var
  I: integer;
begin
  for I := 0 to 1000 do
  begin
    Pb.Position := I;
    Pb.Update;
    Sleep(10);
  end;
end;

Exports
  Process;

通话结束后,我得到访问冲突。但是,在我阅读的dpr文件中注释, ShareMem 写第一行,但效果为零。

请告诉我如何从Delphi DLL正确更新Inno Setup中的进度条。

1 个答案:

答案 0 :(得分:1)

您不能以这种方式调用对象方法。如果您使用完全相同版本的Delphi,您可能会很幸运,因为您使用Delphi应用程序的测试显示。但它仍然是错误和不可靠的,不要这样做。当您使用不同的Delphi版本时,内存中进度条类的布局是不同的,因此“访问冲突”

对于此特定任务,您只需使用进度条的句柄即可轻松完成:

function Process(Handle: THandle): Integer; 
var
 I: Integer;
begin
  SendMessage(Handle, PBM_SETRANGE, 0, 1000 shl 16);
  for I := 0 to 1000 do
  begin
    SendMessage(Handle, PBM_SETPOS, I, 0);   
    UpdateWindow(Handle);
    Sleep(10);
  end;
end;

在Inno Setup中,调用如下函数:

function Count(Handle: THandle): integer; external 'Process@files:CallC.dll stdcall delayload';

procedure NewButton1Click(Sender: TObject);
begin
  Count(NewProgressBar1.Handle);
end;

对于更高级的任务,您需要使用回调。