刚学D  对这块还不是很了解
我想问下我能不能先写个窗体然后把他放到DLL中去? 请问怎么放有什么规则或要求?

解决方案 »

  1.   

    《Delphi 5 开发人员指南》
    第9章   动态链接库 234
    9.4.2   显示DLL中的模式窗体 239
    9.5   显示DLL中的无模式窗体 241
      

  2.   

    在dll中显示窗体会有一些很难解决的问题:无法控制焦点,最大化/最小化出现问题,低级内存访问错误,原因是主控程序和dll中均有一个application和Screen对象,虽然将主控程序的application和screen传入dll中,但仍然无法从根本上解决问题。
    建议用bpl代替dll,bpl是面向对象的,用它构建的系统只能一个screen和application对象。
      

  3.   

    是这样的情况
    我想用DLL HOOK目标程序的进程 然后在 目标程序启动后 按热键将DLL中的窗体呼出(应为DLL窗体里的功能是调用目标程序的自身函数,所以只有在目标程序进程里的窗体才能实现)
      

  4.   

    sdzeng(大头鸟) 的回答,好具体
      

  5.   

    hehe ,刚刚做了一个,给你看看
      

  6.   

    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, StrUtils, ExtCtrls, Unit3, Unit5;type
      TForm1 = class(TForm)
        Button1: TButton;
        Timer2: TTimer;
        Timer1: TTimer;
        procedure Button1Click(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
        procedure Timer2Timer(Sender: TObject);
        procedure Timer1Timer(Sender: TObject);
      private
        { Private declarations }
        readpasswd:Tic;
        states :boolean;
      public
         h:integer;
         passwd:String;
      end;var
      Form1: TForm1;
      hTag,hand: HWND;
      hk_Next: HHOOK;
      SubThreadID:DWORD;
    function HookProc(nCode:integer;wParam: WPARAM; lParam: LPARAM): LResult;stdcall;
    implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
    var
      i:integer;
      s:PChar;
    begin
      hand := FindWindow(nil,'挂号业务');
      if hand<>0 then
      begin
        repeat
        hTag := FindWindowEx(hand,0,'Button',nil);
        s:=strnew('');
        i:=GetWindowTextLength(hTag);
        GetWindowText(hTag,s,i+1);
        if AnsiStartsText('读卡',strpas(s)) then break;
        until hTag=0;
      if (hTag<>0) and (h=0) then
         begin
         hk_Next := SetWindowsHookEx(WH_JOURNALRECORD,@HookProc,HInstance,0);
         Inc(h);
         end;
      end;
    end;procedure TForm1.FormDestroy(Sender: TObject);
    begin
       if (hTag <> 0) and(hk_Next <> 0) then
          UnhookWindowsHookEx(hk_Next);
    end;function HookProc(nCode:integer;wParam: WPARAM; lParam: LPARAM): LResult;
    begin
       Result := HC_ACTION;
        if nCode < 0 then Result := CallNextHookEx(hk_Next, nCode, wParam, lParam)
        else  if nCode = HC_ACTION then begin
          if PEventMsg(lParam)^.message = WM_LBUTTONDOWN then
            if PEventMsg(lParam)^.hwnd = hTag then
            begin
               CreateThread(nil, 0, @ThreadPro, nil, 0, SubThreadID);
            end
            else
            Result := CallNextHookEx(hk_Next, nCode, wParam, lParam);
        end;
    end;procedure TForm1.Timer2Timer(Sender: TObject);var
      hnd:THandle;
      portste:Boolean;
    begin
      hnd := Findwindow('FNWND370',nil);
      if hnd > 0 then
         begin
            readpasswd:=Tic.Create ;
            readpasswd.closeacr ;
            states := true;
            if passwd = '' then
            begin
            portste:=readpasswd.openacr(1);
            if portste then
              begin
                readpasswd.ReadBH ;
                passwd := readpasswd.Read_employee.qt1 ;
              end;
            end;
            readpasswd.Destroy ;
            states := false;
         end ;
      hand := FindWindow(nil,'挂号业务');
      if (hand<>0) then
          begin
           Timer1.Enabled := true;
          end
      else
          begin
           Timer1.Enabled := false;
          end;
    end;procedure TForm1.Timer1Timer(Sender: TObject);
    begin
       hand := FindWindow(nil,'挂号业务');
      if (hand<>0) then
          begin
            Timer2.Enabled := false;
            Button1Click(Sender);
            try
            begin
            if states then begin
               readpasswd.closeacr ;
               readpasswd.Destroy ;
               end;
            end;
            except
            exit;
            end;
          end
      else
         begin
            Timer2.Enabled := true; 
         end;
    end;end.unit  unit3;interfaceconst
      DllMutex = 'zwh_passwd';  // 待插线程回调函数
    procedure ThreadPro(X: Integer); stdcall;implementationuses Windows, Messages, Unit2;  // 待插线程回调函数
    procedure ThreadPro(X: Integer); stdcall;
    var
      MsgStruct: TMsg;
      hMutexObj: DWORD;
      passw:THandle;
    begin
      passw := FindWindow(nil,'请输入密码');
      if passw <> 0 then exit
      else begin
      hMutexObj := CreateMutex(nil, FALSE, DllMutex);
      Register_MainForm;
      Create_MainForm;
      while GetMessage(MsgStruct, 0, 0, 0) do
      begin
        TranslateMessage(MsgStruct);
        DispatchMessage(MsgStruct);
      end;
      Unregister_MainForm;
      CloseHandle(hMutexObj);
    end;
    end;(* 注,这个线程有窗体,也可以用FindWindow来防止重复运行 *)
    end.
      

  7.   

    unit Unit2;interfaceprocedure Register_MainForm;   // 注册窗体类
    procedure Unregister_MainForm; // 撤销窗体类
    procedure Create_MainForm;     // 建立主窗体implementationuses
      Windows, Messages,SysUtils,StrUtils,Unit1;const
      ClassName = 'PassWd_ZWH';
    var
      j:integer=0;  // 窗体过程回调函数
    function FormProc(hForm, MsgID, WParam, LParam: LongWord): LongWord; stdcall;
    const
    {$J+}
      TempFont: DWORD = 0;
    {$J-}
      ControlID1 = 1;
      ControlID2 = 2;
      ControlID3 = 3;
    var
      EditText: array[0..30] of Char;
      i:integer;
      sth:PChar;
      hands,hTagone:longword;
      newpas:string;
    begin
      Result := DefWindowProc(hForm, MsgID, WParam, LParam); // 标准处理
      case MsgID of
        WM_CREATE:
          begin
            TempFont := CreateFont(12, 6, 0, 0, FW_EXTRALIGHT, Byte(FALSE), Byte(FALSE),Byte(FALSE), GB2312_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, '宋体');        CreateWindowEx(0, 'BUTTON', '验证密码', WS_CHILD or WS_VISIBLE,30, 60, 70, 25, hForm, ControlID1, HInstance, nil);
            SendMessage(GetDlgItem(hForm, ControlID1), WM_SETFONT, TempFont, 1);        CreateWindowEx(0, 'BUTTON', '退出程序', WS_CHILD or WS_VISIBLE, 165, 60, 70, 25, hForm, ControlID2, HInstance, nil);
            SendMessage(GetDlgItem(hForm, ControlID2), WM_SETFONT, TempFont, 1);        CreateWindowEx(ES_PASSWORD, 'Edit', '', WS_CHILD or WS_VISIBLE or ES_PASSWORD or WS_BORDER, 15, 20, 230, 20, hForm, ControlID3, HInstance, nil);
            SendMessage(GetDlgItem(hForm, ControlID3), WM_SETFONT, TempFont, 1);
            SETFOCUS(GetDlgItem(hForm, ControlID3));
          end;    WM_COMMAND:
          begin
            if (HIWORD(wParam) = BN_CLICKED) then // 单击按钮
            begin
              case LOWORD(wParam) of // 控件ID
                ControlID1:
                  begin
                    GetWindowText(GetDlgItem(hForm, ControlID3), @EditText[0], 30);
                    newpas:=EditText;
                    if newpas = Form1.passwd then
                       begin
                          hands := FindWindow(nil,'挂号业务');
                          if hands<>0 then
                              begin
                                repeat
                                hTagone := FindWindowEx(hands,0,'Button',nil);
                                sth:=strnew('');
                                i:=GetWindowTextLength(hTagone);
                                GetWindowText(hTagone,sth,i+1);
                                if AnsiStartsText('读卡',strpas(sth)) then break;
                                until hTag=0;
                                strdispose(sth);
                              end;
                              UnhookWindowsHookEx(hk_Next);
                              SendMessage(hForm,WM_CLOSE,0,0);
                              SendMessage(hTagone,WM_LBUTTONDOWN,0,0);
                              SendMessage(hTagone,WM_LBUTTONup,0,0);
                              Form1.h := 0;j:=0; Form1.passwd := '';
                       end
                    else
                       begin
                          if j<2 then
                              begin
                                MessageBox(hForm,'密码错误','提示',MB_OK);
                                SetWindowText(GetDlgItem(hForm, ControlID3),'');
                                SETFOCUS(GetDlgItem(hForm, ControlID3));
                                inc(j);
                              end
                          else
                              begin
                                UnhookWindowsHookEx(hk_Next);
                                hands := FindWindow(nil,'挂号业务');
                                SendMessage(hForm,WM_CLOSE,0,0);
                                SendMessage(hands,WM_CLOSE,0,0);
                                Form1.h := 0;j:=0;
                                Form1.passwd := '';
                              end;
                       end;
                  end;
                ControlID2:
                   begin
                      SendMessage(hForm, WM_CLOSE, 0, 0);
                      j:=0;
                   end;
              end;
            end;          
          end;    WM_DESTROY:
          begin
            PostQuitMessage(0);
            DeleteObject(TempFont);
          end;
      end;
    end;   // 注册窗体类
    procedure Register_MainForm;
    var
      FormClass: TWndClass;
    begin
      FormClass.Style := CS_HREDRAW or CS_VREDRAW;
      FormClass.lpfnWndProc := @FormProc;
      FormClass.cbClsExtra := 0;
      FormClass.cbWndExtra := 0;
      FormClass.hInstance := SysInit.HInstance;
      FormClass.hIcon := LoadIcon(HInstance,'cool');
      FormClass.hCursor :=  LoadCursor(0, IDC_ARROW);
      FormClass.hbrBackground := COLOR_WINDOW;
      FormClass.lpszMenuName := nil;
      FormClass.lpszClassName := ClassName;
      RegisterClass(FormClass);
    end;  // 注销窗体类
    procedure Unregister_MainForm;
    begin
      UnregisterClass(ClassName, HInstance);
    end;      // 建立主窗体
    procedure Create_MainForm;
    begin
      CreateWindowEx(WS_EX_TOPMOST, ClassName, '请输入密码', WS_VISIBLE or WS_TILED , 400, 350, 270, 130, 0, 0, HInstance, nil);
    end;end.
      

  8.   

    dll封装的 窗体 使用MIDI 模式可已嵌入主窗体,但是如果lz想用DOCK的形式恐怕就不行了。我原来也这样做过,使用DOCK的话是不行的。
      

  9.   

    library Hook;uses
      SysUtils,
      System,
      Classes,
      Unit in 'Unit{这就是你的窗体,随便什么都可以},
    {$R *.res}end.