var
  lpTimerProc: Pointer;begin
  lpTimerProc := Pointer(@Self.OnScrollTimer);
end;错误如下:[Error] _Bxxxxx.pas(865): Variable required

解决方案 »

  1.   

    如果把OnScrollTimer作为全局的函数,则lpTimerProc := Pointer(@OnScrollTimer); 是可以的可是我不想弄为全局的,因为我需要Self的指针值。或者谁知道如果在SetTimer()时传递一个结构的地址给OnScrollTimer,如果OnScrollTimer为全局的,我必须向办法把Self的地址传给OnScrollTimer。如果@Self.OnScrollTimer可行,就不必传了。该怎么弄?原始的代码如下:
    lpTimerProc := Pointer(@Self.OnScrollTimer);
    nIDTimer := SetTimer(hwndWB, IDT_SCROLL_TIMER, SCROLL_INTERVAL_TIME, lpTimerProc);
    if nIDTimer <> 0 then
    begin
       ....
    end;
      

  2.   

    lpTimerProc := Pointer(Self.OnScrollTimer);应该就可以了吧!
      

  3.   

    还是错的
    [Error] _BrowserHelp.pas(865): Not enough actual parameters也许我知道怎么做了,申明一个函数指针类型
      

  4.   

    var
      P : Pointer;
    begin
      P := TMethod(Self.OnScrollTimer).Code;
    end;
      

  5.   

    但是成员函数的指针和一般的Procedure/Function不一样。值得注意。
      

  6.   

    还是不行
    [Error] _BrowserHelp.pas(899): Invalid typecast
      

  7.   

    //晕,我这里可以啊。
    var
      P : Pointer;
    begin
      P := TMethod(Self.OnMouseMove).Code;
    end;你的OnScrollTimer是个什么样子的过程?
      

  8.   

    procedure TBrxxxxx.OnScrollTimer(uMsg: UINT; idEvent: UINT; dwTime: DWORD); stdcall;我试试你的
      

  9.   

    Type
      TOnScrollTimerEvent=Procedure (Value:Integer) of object;TTest_Obj=Class
      procedure OnScrollTimer(Value:Integer);
    end;
    vea
     AOnScrollTimer:TOnScrollTimerEvent;
    begin
    AOnScrollTimer:=Self.OnScrollTimer;
    end;
      

  10.   

    to kiboisme(蓝色光芒):我的还是不行,为什么你的可以?我的类是派生自TComObject,不会是因为这个吧,我是Delphi 7to ZyxIp(绝望中...):先下班了,明天再试试你的代码,谢谢
      

  11.   

    ……晕……Object Pascal的Event不是4字节的指针,是8字节的!这和C++的“类方法指针”有点类似,不过C++的类方法指针内保存的是入口地址或VMT索引、调用约定、是否为virtual等等;Object Pascal保存的是实例指针(Self)、调用约定、VMT索引,但不用保存是否为virtual,因为Object Pascal的编译器将Event Handler Method一律编译为Dynamic,不管你用了什么指示字(常规、virtual、dynamic)。你是没得选的,把Callback连接到一个事件只能加一个wrapper的。另……郭子你消失那么多年了,现在在哪里混?
      

  12.   

    Type
      TComEventProc = Procedure(uMsg: UINT; idEvent: UINT; dwTime: DWORD); stdcall;
      TCOMOBJ_Test = Class(TComObject)
      private
        F : TComEventProc;
      public
        property OnEvent : TComEventProc read F Write F;
      published
      end;var
      Obj : TCOMOBJ_Test;
      P1 : Pointer;
    begin
      //OBJ := TCOMOBJ_Test.Create;//这样直接创建要出错。^_^
      P1 := @OBJ.OnEvent;
      if P1 = NIL then exit;
    end;
    直接就可以编译,我不知道你是不是这个意思?
      

  13.   

    to Scarlette(Lord of Borland):陶,好多年没有看见你了,真是巧啊,你竟然这么有空:)时常都会想起原来在上海的同事,你,海峰,李锐,老刀(其实偶是个比较怀旧的人)。我现在在湖南株洲混(原来的一个北京同事自己搞的小公司),你最近玩暴雪的魔兽世界么,我现在和朱海峰同学还有一帮年轻人一块玩:)我们在一区,我估计你也在玩了,这个东西是当初朱海峰2001年告诉我的,结果却是我玩得比较多,去年在家呆了一年玩了很久WoW欧服,现在在一家小公司混饭吃,挣点Money玩WoW。to kiboisme(蓝色光芒):碰上老朋友了,心情比较高兴,大概是这样的,我在写一个IE拦截Flash,广告的插件,其中拦截浮动广告的部分,由于无法在BHO(Browser Helper Object)里响应IE的onScroll事件,所以只能用个定时器,在OnTimer里(也就是我自己写的回调函数OnScrollTimer,因为BHO是IE的组件不是窗体,没有WindowProc,也就不能用默认的OnTimer事件)定时的拦截浮动广告的DIV层(好像3721也是这样干的,不是即时拦截的,大概也是用定时器),由于在OnScrollTimer里必须调用类成员变量,无法使用全局的变量(因为IE有可能一个进程可以开多个窗体,每个窗体都会启动一次BHO组件)lpTimerProc := Pointer(@OnScrollTimer);  // OnScrollTimer写成全局的肯定是可以的lpTimerProc := Pointer(@TBrowserHelp.OnScrollTimer);  // 如果OnScrollTimer写成类成员函数,但这样也类似于C++的类static成员函数,它没有Self指针,所以会出错nIDTimer := SetTimer(hwndWB, IDT_SCROLL_TIMER, SCROLL_INTERVAL_TIME, lpTimerProc);不过我现在想到解决的办法了,在OnScrollTimer里通过hwnd转换出IE的IWebbrowser2或IHTMLDocument2接口,不过目前hwnd有点问题,吃饭先,回来再讨论
      

  14.   

    to ZyxIp(绝望中...)
      像你那样可以,但是一样没有Self指针to kiboisme(蓝色光芒):
    var
      Obj : TCOMOBJ_Test;
      P1 : Pointer;
    begin
      //OBJ := TCOMOBJ_Test.Create;//这样直接创建要出错。^_^
      P1 := @OBJ.OnEvent;        // *** 估计这里跟 P1 := @TCOMOBJ_Test.OnEvent; 是一样的
      if P1 = NIL then exit;
    end;另……问题已经解决,我已经可以把hwnd转换成相应的IWebBrowser2,代码如下:function GetIEFromHWND(WHandle: HWND; var IE: IWebbrowser2): HRESULT;
    var
        hInst: HWND;
        lRes: Cardinal;
        MSG: Integer;
        pDoc: IHTMLDocument2;
        ObjectFromLresult: TObjectFromLresult;
    begin
        Result := S_FALSE;
        hInst := LoadLibrary('Oleacc.dll');
        if hInst <> 0 then
        begin
            @ObjectFromLresult := GetProcAddress(hInst, 'ObjectFromLresult');
            if @ObjectFromLresult <> nil then
            begin
                try
                    MSG := RegisterWindowMessage('WM_HTML_GETOBJECT');                SendMessageTimeOut(WHandle, MSG, 0, 0, SMTO_ABORTIFHUNG, 50, lRes);  // 这里用50ms会不会太短了?我程序好像有点慢,所以我改为这个值,一帮用1000ms
                    Result := ObjectFromLresult(lRes, IHTMLDocument2, 0, pDoc);
                    if Result = S_OK then
                    begin
                        (pDoc.parentWindow as IServiceprovider).QueryService(IWebbrowserApp, IWebbrowser2, IE);
                    end;
                finally
                    // do nothing
                end;
            end;
            FreeLibrary(hInst);
        end;
    end;function GetIEFromWBHWND(hwndWB: HWND; var IE: IWebbrowser2): HRESULT;
    var
    WndChild: Integer;
    begin
    Result := S_FALSE;
    // walk Shell DocObject View->Internet Explorer_Server
    WndChild := FindWindowEX(hwndWB, 0, 'Shell DocObject View', nil);
        if WndChild <> 0 then
        begin
         WndChild := FindWindowEX(WndChild, 0, 'Internet Explorer_Server', nil);
            if WndChild <> 0 then
             Result := GetIEFromHWND(WndChild, IE); // Get Iwebbrowser2 from Handle
        end;
    end;