我从网上下了两个dll,查了些资料,看了dll的编译过程,也仔细看了这两个dll的源码,我现在有个问题:我把这两个dll工程转到另一个地方,可以成功的生成dll文件,但我把引用这两个dll的exe转到另一个地方去的时候,编译的时候就无论如何也通不过,总是提示说什么缺少dcu文件;于是我回过头来看我下载的源码,发现在那两个dll工程的位置,还分别有两个pas文件,可我查找的大部分关于编写dll的资料中都根本就没有提到过pas文件;我又查了些资料,根据pas文件可以生成dcu文件,于是我就照步骤做了;当我把两个dcu文件转到我原来试验的地方,我原来的exe就立即编译成功了,,
我的问题就是:那两个PAS文件该怎样写啊?????我看了看PAS文件里的代码,完全不知所云,比那两个dll里的源代码还要让我费解...不要笑我,我初次接触delphi,请大虾帮忙给我解释一下....

解决方案 »

  1.   

    你看看工程文件里有没有这两个pas文件,有的话就一起COPY过去就是了
      

  2.   

    把代码贴出来让大家看看吧,Dcu是中间文件,有些程序需要调用接口,但是作者不愿意公开接口,就做成dcu的形式,让你看不到源码
      

  3.   

    另外,Pas就是Pascal代码文件,俗称“源码”……
      

  4.   

    两个pas文件一个键盘的,一个是鼠标的,我没有什么调用,我就是直接把源文件拷到另一个位置,就发现了这个问题,关键是,我拷贝dll源代码,没问题,可以生成dll,我拷贝exe,就提示说找不到dcu文件,下面是两个pas:{ MouseHook DLL Load & TMouseHook Class Unit 2004-09-08 Copyright ? Thomas Yao // OnKeyUp does't work}unit KeyboardHook;interfaceuses
      Windows, Messages, Classes;const
      DEFDLLNAME = 'keyboardhook.dll';
      MappingFileName = '57D6A971_KeyboardHookDLL_442C0DB1';
      MSGKEYDOWN: PChar = 'MSGKEYDOWN57D6A971-049B-45AF-A8CD-37E0B706E036';
      MSGKEYUP: PChar = 'MSGKEYUP442C0DB1-3198-4C2B-A718-143F6E2D1760';type
      TMappingMem = record
        Handle: DWORD;
        MsgID: DWORD;
        KeyCode: DWORD;
      end;
      PMappingMem = ^TMappingMem;  TEnableKeyboardHook = function(hWindow: HWND): BOOL; stdcall;  TDisableKeyboardHook = function: BOOL; stdcall;  TKeyDownNotify = procedure(const KeyCode: Integer) of object;  TKeyUpNotify = procedure(const KeyCode: Integer) of object;  TKeyboardHookBase = class
      private
        FDLLName: string;
        FDLLLoaded: BOOL;
        FListenerHandle: HWND;
        FActive: BOOL;
        hMappingFile: THandle;
        pMapMem: PMappingMem;
        procedure WndProc(var Message: TMessage);
        procedure SetDLLName(const Value: string);
      protected
        MSG_KEYDOWN: UINT;
        MSG_KEYUP: UINT;
        procedure ProcessMessage(var Message: TMessage); virtual; abstract;
      public
        constructor Create; virtual;
        destructor Destroy; override;
        function Start: BOOL; virtual;
        procedure Stop; virtual;
        property DLLLoaded: BOOL read FDLLLoaded;
        property Active: BOOL read FActive;
      published
        property DLLName: string read FDLLName write SetDLLName;
      end;  TKeyboardHook = class(TKeyboardHookBase)
      private
        FOnKeyDown: TKeyDownNotify;
        FOnKeyUp: TKeyUpNotify;
        procedure DoKeyDown(const KeyCode: Integer);
        procedure DoKeyUp(const KeyCode: Integer);
      protected
        procedure ProcessMessage(var Message: TMessage); override;
      public  published
        property DLLName;
        property OnKeyDown: TKeyDownNotify read FOnKeyDown write FOnKeyDown;
        property OnKeyUp: TKeyUpNotify read FOnKeyUp write FOnKeyUp;
      end;var
      DLLLoaded: BOOL = False;  StartKeyboardHook: TEnableKeyboardHook;
      StopKeyboardHook: TDisableKeyboardHook;implementationvar
      DLLHandle: HMODULE;procedure UnloadDLL;
    begin
      DLLLoaded := False;  if DLLHandle <> 0 then
      begin
        FreeLibrary(DLLHandle);
        DLLHandle := 0;
        @StartKeyboardHook := nil;
        @StopKeyboardHook := nil;
      end;
    end;function LoadDLL(const FileName: string): Integer;
    begin
      Result := 0;  if DLLLoaded then
        Exit;  DLLHandle := LoadLibraryEx(PChar(FileName), 0, 0);
      if DLLHandle <> 0 then
      begin
        DLLLoaded := True;    @StartKeyboardHook := GetProcAddress(DLLHandle, 'EnableKeyboardHook');
        @StopKeyboardHook := GetProcAddress(DLLHandle, 'DisableKeyboardHook');    if (@StartKeyboardHook = nil) or (@StopKeyboardHook = nil) then
        begin
          Result := 0;
          UnloadDLL;
          Exit;
        end;    Result := 1;
      end
      else
        MessageBox(0, PChar(DEFDLLNAME + ' library could not be loaded !'),
          'Error', MB_ICONERROR);
    end;{ TInputHook }constructor TKeyboardHookBase.Create;
    begin
      pMapMem := nil;
      hMappingFile := 0;
      FDLLName := DEFDLLNAME;
      MSG_KEYDOWN := RegisterWindowMessage(MSGKEYDOWN);
      MSG_KEYUP := RegisterWindowMessage(MSGKEYUP);
    end;destructor TKeyboardHookBase.Destroy;
    begin
      Stop;
      inherited;
    end;procedure TKeyboardHookBase.WndProc(var Message: TMessage);
    begin
      if pMapMem = nil then
      begin
        hMappingFile := OpenFileMapping(FILE_MAP_WRITE, False, MappingFileName);
        if hMappingFile = 0 then
          MessageBox(0, 'cannot create share memory!', 'Error', MB_OK or MB_ICONERROR);
        pMapMem := MapViewOfFile(hMappingFile, FILE_MAP_WRITE or FILE_MAP_READ, 0, 0, 0);
        if pMapMem = nil then
        begin
          CloseHandle(hMappingFile);
          MessageBox(0, 'cannot map share memory!', 'Error', MB_OK or MB_ICONERROR);
        end;
      end;
      if pMapMem = nil then
        Exit;  if (Message.Msg = MSG_KEYDOWN) or (Message.Msg = MSG_KEYUP) then
      begin
        Message.WParam := pMapMem.KeyCode;
        ProcessMessage(Message);
      end
      else
        Message.Result := DefWindowProc(FListenerHandle, Message.Msg, Message.wParam,
          Message.lParam);
    end;function TKeyboardHookBase.Start: BOOL;
    var
      hookRes: Integer;
    begin
      Result := False;
      if (not FActive) and (not FDLLLoaded) then
      begin
        if FDLLName = '' then
        begin
          Result := False;
          Exit;
        end
        else
        begin
          hookRes := LoadDLL(FDLLName);
          if hookRes = 0 then
          begin
            Result := False;
            Exit;
          end
          else
          begin
            FListenerHandle := AllocateHWnd(WndProc);
            if FListenerHandle = 0 then
            begin
              Result := False;
              Exit;
            end
            else
            begin
              if StartKeyboardHook(FListenerHandle) then
              begin
                Result := True;
                FDLLLoaded := True;
                FActive := True;
              end
              else
              begin
                Result := False;
                Exit;
              end;
            end;
          end;
        end;
      end;
    end;procedure TKeyboardHookBase.Stop;
    begin
      if FActive then
      begin
        if FListenerHandle <> 0 then
        begin
          pMapMem := nil;
          if hMappingFile <> 0 then
          begin
            CloseHandle(hMappingFile);
            hMappingFile := 0;
          end;
          DeallocateHWnd(FListenerHandle);
          StopKeyboardHook;
          FListenerHandle := 0;
        end;
        UnloadDLL;
        FActive := False;
        FDLLLoaded := False;
      end;
    end;procedure TKeyboardHookBase.SetDLLName(const Value: string);
    begin
      if FActive then
        MessageBox(0, 'Cannot activate hook because DLL name is not set.',
          'Info', MB_OK + MB_ICONERROR)
      else
        FDLLName := Value;
    end;{ TKeyboardHook }procedure TKeyboardHook.DoKeyDown(const KeyCode: Integer);
    begin
      if Assigned(FOnKeyDown) then
        FOnKeyDown(KeyCode);
    end;procedure TKeyboardHook.DoKeyUp(const KeyCode: Integer);
    begin
      if Assigned(FOnKeyUp) then
        FOnKeyUp(KeyCode);
    end;procedure TKeyboardHook.ProcessMessage(var Message: TMessage);
    begin
      if Message.Msg = MSG_KEYDOWN then
      begin
        DoKeyDown(Message.WParam);
      end
      else if Message.Msg = MSG_KEYUP then
      begin
        DoKeyUp(Message.WParam);
      end;
    end;end.
      

  5.   

    ////////////////////////////////////////////////////////////////////下面是鼠标pas{ MouseHook DLL Load & TMouseHook Class Unit
     
     2004-09-08
     
     Copyright ? Thomas Yao}unit MouseHook;interfaceuses
      Windows, Messages, Classes;const
      DEFDLLNAME = 'mousehook.dll';
      MappingFileName = '57D6A971_MouseHookDLL_442C0DB1';
      MSGMOUSEMOVE: PChar = 'MSGMOUSEMOVE57D6A971-049B-45AF-A8CD-37E0B706E036';
      MSGMOUSECLICK: PChar = 'MSGMOUSECLICK442C0DB1-3198-4C2B-A718-143F6E2D1760';type
      // 全局映像文件, 如果没有TMappingMem, hook就只对本进程起作用
      TMappingMem = record
        Handle: DWORD;
        MsgID: DWORD;
        MouseStruct: TMOUSEHOOKSTRUCT;
      end;
      PMappingMem = ^TMappingMem;  // 函数原型
      TEnableMouseHook = function(hWindow: HWND; Blocked: BOOL): BOOL; stdcall;  TDisableMouseHook = function: BOOL; stdcall;  // 事件对象
      TMouseMoveNotify = procedure(const Handle: HWND; const X, Y: Integer) of object;  TMouseClickNotify = procedure(const Handle: HWND; const X, Y: Integer) of object;  // 基类
      TMouseHookBase = class
      private
        FDLLName: string;
        FDLLLoaded: BOOL;
        FListenerHandle: HWND;
        FActive: BOOL;
        hMappingFile: THandle;
        pMapMem: PMappingMem;
        FBlocked: BOOL;
        procedure WndProc(var Message: TMessage);
        procedure SetDLLName(const Value: string);
        procedure SetBlocked(const Value: BOOL);
      protected
        MSG_MOUSEMOVE: UINT;
        MSG_MOUSECLICK: UINT;
        // 消息到事件
        procedure ProcessMessage(var Message: TMessage); virtual; abstract;
      public
        constructor Create; virtual;
        destructor Destroy; override;
        function Start: BOOL; virtual;
        procedure Stop; virtual;
        property DLLLoaded: BOOL read FDLLLoaded;
        property Active: BOOL read FActive;
      published
        property DLLName: string read FDLLName write SetDLLName;
        property Blocked: BOOL read FBlocked write SetBlocked;
      end;  // 子类TMouseHook, 只提供事件接口实现
      TMouseHook = class(TMouseHookBase)
      private
        FOnMouseMove: TMouseMoveNotify;
        FOnMouseClick: TMouseClickNotify;
        procedure DoMouseMove(const Handle: HWND; const X, Y: Integer);
        procedure DoMouseClick(const Handle: HWND; const X, Y: Integer);
      protected
        procedure ProcessMessage(var Message: TMessage); override;
      public  published
        property DLLName;
        property OnMouseMove: TMouseMoveNotify read FOnMouseMove write FOnMouseMove;
        property OnMouseClick: TMouseClickNotify read FOnMouseClick write FOnMouseClick;
      end;var
      // 全局变量
      DLLLoaded: BOOL = False;  StartMouseHook: TEnableMouseHook;
      StopMouseHook: TDisableMouseHook;implementationvar
      DLLHandle: HMODULE;procedure UnloadDLL;                    // 卸载dll
    begin
      DLLLoaded := False;  if DLLHandle <> 0 then
      begin
        FreeLibrary(DLLHandle);
        DLLHandle := 0;
        // 释放函数指针
        @StartMouseHook := nil;
        @StopMouseHook := nil;
      end;
    end;function LoadDLL(const FileName: string): Integer; // 加载dll
    begin
      Result := 0;  if DLLLoaded then
        Exit;  DLLHandle := LoadLibraryEx(PChar(FileName), 0, 0);
      if DLLHandle <> 0 then
      begin
        DLLLoaded := True;    // 传递函数指针
        @StartMouseHook := GetProcAddress(DLLHandle, 'EnableMouseHook');
        @StopMouseHook := GetProcAddress(DLLHandle, 'DisableMouseHook');    if (@StartMouseHook = nil) or (@StopMouseHook = nil) then
        begin
          Result := 0;
          UnloadDLL;
          Exit;
        end;    Result := 1;
      end
      else
        MessageBox(0, PChar(DEFDLLNAME + ' library could not be loaded !'),
          'Error', MB_ICONERROR);
    end;{ TInputHook }constructor TMouseHookBase.Create;
    begin
      pMapMem := nil;
      hMappingFile := 0;
      FDLLName := DEFDLLNAME;
      FBlocked := True;
      // 产生独一无二的消息id
      MSG_MOUSEMOVE := RegisterWindowMessage(MSGMOUSEMOVE);
      MSG_MOUSECLICK := RegisterWindowMessage(MSGMOUSECLICK);
    end;destructor TMouseHookBase.Destroy;
    begin
      Stop;
      inherited;
    end;procedure TMouseHookBase.WndProc(var Message: TMessage);
    begin
      if pMapMem = nil then
      begin
        hMappingFile := OpenFileMapping(FILE_MAP_WRITE, False, MappingFileName);
        if hMappingFile = 0 then
          MessageBox(0, 'cannot create share memory!', 'Error', MB_OK or MB_ICONERROR);
        pMapMem := MapViewOfFile(hMappingFile, FILE_MAP_WRITE or FILE_MAP_READ, 0, 0, 0);
        if pMapMem = nil then
        begin
          CloseHandle(hMappingFile);
          MessageBox(0, 'cannot map share memory!', 'Error', MB_OK or MB_ICONERROR);
        end;
      end;
      if pMapMem = nil then
        Exit;  // 消息过滤
      if (Message.Msg = MSG_MOUSEMOVE) or (Message.Msg = MSG_MOUSECLICK) then
      begin
        Message.WParam := pMapMem.MouseStruct.hwnd;
        Message.LParam := (pMapMem.MouseStruct.pt.X and $FFFF) or
          (pMapMem.MouseStruct.pt.Y shl 16);
        ProcessMessage(Message);
      end
      else
        // 不需要处理的消息交给OS默认处理函数
        Message.Result := DefWindowProc(FListenerHandle, Message.Msg, Message.wParam,
          Message.lParam);
    end;function TMouseHookBase.Start: BOOL;
    var
      hookRes: Integer;
    begin
      Result := False;
      if (not FActive) and (not FDLLLoaded) then
      begin
        if FDLLName = '' then
        begin
          Result := False;
          Exit;
        end
        else
        begin
          hookRes := LoadDLL(FDLLName);
          if hookRes = 0 then
          begin
            Result := False;
            Exit;
          end
          else
          begin
            // 这是关键所在, 通过AllocateHWnd创建一个不可见的窗体, 来实现所有消息的中转
            // 通过TMouseHookBase的WndProc来实现对消息的响应
            FListenerHandle := AllocateHWnd(WndProc);
            if FListenerHandle = 0 then
            begin
              Result := False;
              Exit;
            end
            else
            begin
              if StartMouseHook(FListenerHandle, FBlocked) then
              begin
                Result := True;
                FDLLLoaded := True;
                FActive := True;
              end
              else
              begin
                Result := False;
                Exit;
              end;
            end;
          end;
        end;
      end;
    end;procedure TMouseHookBase.Stop;
    begin
      if FActive then
      begin
        if FListenerHandle <> 0 then
        begin
          pMapMem := nil;
          if hMappingFile <> 0 then
          begin
            CloseHandle(hMappingFile);
            hMappingFile := 0;
          end;
          DeallocateHWnd(FListenerHandle);
          StopMouseHook;
          FListenerHandle := 0;
        end;
        UnloadDLL;
        FActive := False;
        FDLLLoaded := False;
      end;
    end;procedure TMouseHookBase.SetDLLName(const Value: string);
    begin
      if FActive then
        MessageBox(0, 'Cannot activate hook because DLL name is not set.',
          'Info', MB_OK + MB_ICONERROR)
      else
        FDLLName := Value;
    end;procedure TMouseHookBase.SetBlocked(const Value: BOOL);
    begin
      if FActive then
        MessageBox(0, 'Cannot set block property of hook because hook is active!',
          'Info', MB_OK + MB_ICONERROR)
      else
        FBlocked := Value;
    end;{ TMouseHook }procedure TMouseHook.DoMouseClick(const Handle: HWND; const X, Y: Integer);
    begin
      if Assigned(FOnMouseClick) then
        FOnMouseClick(Handle, X, Y);
    end;procedure TMouseHook.DoMouseMove(const Handle: HWND; const X, Y: Integer);
    begin
      if Assigned(FOnMouseMove) then
        FOnMouseMove(Handle, X, Y);
    end;procedure TMouseHook.ProcessMessage(var Message: TMessage);
    begin
      if Message.Msg = MSG_MOUSEMOVE then
      begin
        DoMouseMove(Message.WParam, Message.LParamLo, Message.LParamHi);
      end
      else if Message.Msg = MSG_MOUSECLICK then
      begin
        DoMouseClick(Message.WParam, Message.LParamLo, Message.LParamHi);
      end;
    end;end.
      

  6.   

    TKeyboardHook = class(TKeyboardHookBase) 
    TMouseHook = class(TMouseHookBase我想这两个pas文件可能的确提供了两个接口,如果没有这两个pas生成的dcu文件,我原来的exe中,编译的时候就会停在这个地方:    mhook: TMouseHook;
        khook: TKeyboardHook;上两句都是在Type里的.还请大家帮忙帮我看一下,这两个pas文件该怎样写呢?应该学习哪方面的内容呢?这两个文件里的内容,跟我单纯搜索dll得到的资料完全不是一个概念..在读这些代码的时候我感觉相当累..
      

  7.   

    Exe只是调用Dll,DLL编译通过了,理论上和dcu没什么关系.
    另外,你那两个Pas,明显就是DLL里面的单元文件,想知道怎么写只能看书了,windows编程相关的书籍,有一本书<<Delphi下深入windows核心编程>>,有兴趣可以看看
      

  8.   

    主工程引用这了两个PAS吧,DLL能译就是没有引用这两个
      

  9.   

    主工程没有引用这两个PAS,我就是看不出dll与这两个pas有什么关系,dll的工程文件拷贝到另一个地方也可以生成dll,生成dll之后如果没有dcu文件, dll文件调用就不成功,必须把dcu文件摆在exe相同位置,不然我就不来这问了.
      

  10.   

    如果没有dcu文件,exe就编译不通过,必须把dcu摆在exe工程地址下..
      

  11.   

    我知道了,主工程引用的是这两个pas文件!!!跟dll没关系,是exe在引用这两个pas