比如一个程序1.exe我已经知道该程序的 进程句柄.该如何得到该进程的主窗口句柄?
我搜索过,知道要枚举所有窗口句柄,然后把枚举出来的窗口的进程句柄比对,如果相同就是了
然后我在网上找到例子,调试出错.请教前辈怎么枚举所有窗口,并且取其进程句柄,然后相比.谢谢 hProcess := OpenProcess(PROCESS_ALL_ACCESS, False,PID);这是已知的条件hProcess是知道的句柄.请求源码,感谢!!好人一生平安~

解决方案 »

  1.   

    FindWindow遍历窗体,找出对应窗体。
      

  2.   

    HWND HelpHwnd = (void*)-1 ;struct   EnumParam
    {
        HWND hMainWnd;
        DWORD dwProcessID;
    };BOOL CALLBACK EnumWinProc(HWND hwnd, LPARAM lParam)
    {
        DWORD dwID;
        EnumParam* pep = (EnumParam*)lParam;
        GetWindowThreadProcessId(hwnd,   &dwID);
        if (dwID == pep->dwProcessID)
        {
            pep->hMainWnd = hwnd;
            return FALSE;
        }
        return  TRUE;
    }
    //---------------------------------------------------------------------------
    void InvokeHelp()
    {
        String helpFile = ".\\HelpDoc.chm";
        if (!FileExists(helpFile))
        {
            return;
        }   Sleep(1000);//如果不延时的话,恐怕查到的是杀掉的进程    HWND hwnd = FindWindowEx(NULL, HelpHwnd, NULL, NULL);
        if (hwnd == NULL)
        {
            EnumParam ep;
            STARTUPINFO si;
            PROCESS_INFORMATION pi;
            ep.hMainWnd = NULL;
            memset(&si, 0, sizeof(si));
            si.cb = sizeof(STARTUPINFO);
            helpFile = "hh  " +  helpFile;
            if (CreateProcess(NULL, helpFile.c_str(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
            {
                Sleep(1000); //如果不延时的话,恐怕进程列表未及时刷新
                CloseHandle(pi.hThread);
                CloseHandle(pi.hProcess);
                ep.dwProcessID = pi.dwProcessId;
                EnumWindows((WNDENUMPROC)EnumWinProc, (long)&ep);
                HelpHwnd = ep.hMainWnd;
            }
        }
        else
        {
            SetForegroundWindow(HelpHwnd);
            SetActiveWindow(HelpHwnd);
        }
    }
      

  3.   

    參考:http://blog.csdn.net/Avan_Lau/archive/2010/02/03/5285074.aspx
      

  4.   

    您发的这个文章我在http://topic.csdn.net/u/20100119/15/F22E99D8-549C-4CE9-BA15-5FFC4F584D68.html这里已经参考过了,调试出错请看我源码unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ExtCtrls,TLHelp32;type
      TForm1 = class(TForm)
        Button1: TButton;
        Edit1: TEdit;
        Label1: TLabel;
        Label2: TLabel;
        Edit2: TEdit;
        procedure Button1Click(Sender: TObject);  private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;
    implementation{$R *.dfm}
    function GetProcessID(ProcessName:string):TProcessEntry32;
    var
      lppe: TProcessEntry32;
      found : boolean;
      Hand : THandle;
      P:DWORD;
      s:string;begin
      FillChar(result,SizeOf(TProcessEntry32),0);
      Hand := CreateToolhelp32Snapshot(TH32CS_SNAPALL,0);
      lppe.dwSize := Sizeof(lppe);  while found do
      begin
        s := string(lppe.szExeFile);
        if lppe.th32ProcessID>0 then
          p := lppe.th32ProcessID
        else
          p := 0;
        if UpperCase(ExtractFileName(s))=UpperCase(ExtractFileName(ProcessName)) then
        begin
          GetProcessID:=lppe;
          break;
        end;
        found := Process32Next(Hand,lppe);
      end;
    end;
    procedure TForm1.Button1Click(Sender: TObject);
    var
    Retlppe:TProcessEntry32;
    s,x:integer  ;
    hProcess: THandle;
    PID:DWORD;
    vNumberOfBytesWritten: DWORD;
    OldTokenPrivileges, TokenPrivileges: TTokenPrivileges; 
    ReturnLength: dword; 
    hToken: THandle; 
    Luid: int64; begin
    Retlppe := GetProcessID('1.exe');
    PID:=Retlppe.th32ProcessID;  //得到进程ID
    hProcess := OpenProcess(PROCESS_ALL_ACCESS, False,PID);   //得到句柄end;function TForm1.GetHWndByPID(const hPID: THandle): THandle;
    type
        PEnumInfo = ^TEnumInfo;
        TEnumInfo = record
        ProcessID: DWORD;
        HWND: THandle;
        end;    function EnumWindowsProc(Wnd: DWORD; var EI: TEnumInfo): Bool; stdcall;
        var
        PID: DWORD;
        begin
        GetWindowThreadProcessID(Wnd, @PID);
        Result := (PID <> EI.ProcessID) or
            (not IsWindowVisible(WND)) or
            (not IsWindowEnabled(WND));    if not Result then EI.HWND := WND; 
        end;    function FindMainWindow(PID: DWORD): DWORD;
        var
        EI: TEnumInfo;
        begin
        EI.ProcessID := PID;
        EI.HWND := 0;
        EnumWindows(@EnumWindowsProc, Integer(@EI));
        Result := EI.HWND;
        end;
    begin
        if hPID<>0 then
        Result:=FindMainWindow(hPID)
        else
        Result:=0;
    end;
    end.请前辈们指点,
    谢谢,
      

  5.   

    function GetHWndByPID(const hPID: THandle): THandle;
    這段放在TForm1定義部分申明
      

  6.   

    驗證一下:    function EnumWindowsProc(Wnd: DWORD; var EI: TEnumInfo): Bool; stdcall;
        var
          PID: DWORD;
        begin
          GetWindowThreadProcessID(Wnd, @PID);
    //    Result := (PID <> EI.ProcessID) or
    //        (not IsWindowVisible(WND)) or
    //        (not IsWindowEnabled(WND));
        //應該這么寫
          if PID = EI.ProcessID then
          begin 
            Result := False;
            EI.HWND := WND;   
          end;
        end;
      

  7.   

    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls,PsAPI;type
      TForm1 = class(TForm)
        Button1: TButton;
        Memo1: TMemo;
        Button2: TButton;
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
         type
        EnumWindowsProc = function (Hwnd: THandle;
          Param: Pointer): Boolean; stdcall;var
      Form1: TForm1;implementation{$R *.dfm}function GetPath(hWnd:HWND):string;   
    var hProcessID, hProcess: THandle;
        hMod: HMODULE;
        Size: DWORD;
        Buf: array[0..255] of char;
    begin
      GetWindowThreadProcessId(hWnd, @hProcessID);
      hProcess:= OpenProcess(PROCESS_ALL_ACCESS, False, hProcessID);
      EnumProcessModules(hProcess, @hMod, SizeOf(hMod), Size);
      GetModuleFileNameEx(hProcess, hMod, Buf, SizeOf(Buf));
      CloseHandle(hProcess);
      Result:=ExtractFilename(StrPas(Buf));
    end;
    //**************************************************
    function GetTitlesend (h: THandle; Param: Pointer): Boolean; stdcall;
    var
     buf:array[0..255] of char;
       buff:array[0..255] of char;
      text:array [0..12] of string;
      txt:string;
    begin
        result:=true;
       if GetPath(h)='taskmgr.exe' then
       begin
        while   GetParent(h)   <>   0   do
        begin
         h:=   GetParent(h);
        end;
         showmessage(inttostr(h));
         result:=false;
        end;end;procedure TForm1.Button1Click(Sender: TObject);
    var
        EWProc: EnumWindowsProc;
    begin
      EWProc := GetTitlesend;
      EnumWindows (@EWProc, 0);
    end;
    弹出来的就是你想要的
      

  8.   

    调试通过,我现在该怎么把这个窗口句柄放到BUTTON1的单击事件里?现在的源码,,,成功后结贴试下11楼的
      

  9.   

    [code=Delphi(Pascal)]unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ExtCtrls,TLHelp32;type
      TForm1 = class(TForm)
        Button1: TButton;
        Edit1: TEdit;
        Label1: TLabel;
        Label2: TLabel;
        Edit2: TEdit;
        Edit3: TEdit;
        Button2: TButton;
        procedure Button1Click(Sender: TObject);
       function GetHWndByPID(const hPID: THandle):THandle;
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;
    implementation{$R *.dfm}
    function GetProcessID(ProcessName:string):TProcessEntry32;
    var
      lppe: TProcessEntry32;
      found : boolean;
      Hand : THandle;
      P:DWORD;
      s:string;begin
      FillChar(result,SizeOf(TProcessEntry32),0);
      Hand := CreateToolhelp32Snapshot(TH32CS_SNAPALL,0);
      lppe.dwSize := Sizeof(lppe);  while found do
      begin
        s := string(lppe.szExeFile);
        if lppe.th32ProcessID>0 then
          p := lppe.th32ProcessID
        else
          p := 0;
        if UpperCase(ExtractFileName(s))=UpperCase(ExtractFileName(ProcessName)) then
        begin
          GetProcessID:=lppe;
          break;
        end;
        found := Process32Next(Hand,lppe);
      end;
    end;
    procedure TForm1.Button1Click(Sender: TObject);
    var
    Retlppe:TProcessEntry32;
    s,x:integer  ;
    hProcess: THandle;
    PID:DWORD;
    vNumberOfBytesWritten: DWORD;
    OldTokenPrivileges, TokenPrivileges: TTokenPrivileges; 
    ReturnLength: dword; 
    hToken: THandle; 
    Luid: int64; begin
    Retlppe := GetProcessID('zzllk.exe');
    PID:=Retlppe.th32ProcessID;  //得到进程ID
    hProcess := OpenProcess(PROCESS_ALL_ACCESS, False,PID);   //得到句柄end;function TForm1.GetHWndByPID(const hPID: THandle): THandle;
    type
        PEnumInfo = ^TEnumInfo;
        TEnumInfo = record
        ProcessID: DWORD;
        HWND: THandle;
        end;    function EnumWindowsProc(Wnd: DWORD; var EI: TEnumInfo): Bool; stdcall;
        var
        PID: DWORD;
        begin
        GetWindowThreadProcessID(Wnd, @PID);
          if PID = EI.ProcessID then
          begin 
            Result := False;
            EI.HWND := WND;   
          end;
        end;    function FindMainWindow(PID: DWORD): DWORD;
        var
        EI: TEnumInfo;
        begin
        EI.ProcessID := PID;
        EI.HWND := 0;
        EnumWindows(@EnumWindowsProc, Integer(@EI));
        Result := EI.HWND;
        end;
    begin
        if hPID<>0 then
        Result:=FindMainWindow(hPID)
        else
        Result:=0;
        edit3.Text :=inttostr(Result);
    end;
    end.
    [/code]现在的源码
      

  10.   

    to 仙女:
    若在delphi程序中,這樣取到的是application創建的那個看不見的窗口。因為delphi的form,創建時,都指定parent handle為application.handle。
      

  11.   


    procedure TForm1.Button1Click(Sender: TObject);
    var
      Retlppe:TProcessEntry32;
      s,x:integer  ;
      hProcess: THandle;
      PID:DWORD;
      vNumberOfBytesWritten: DWORD;
      OldTokenPrivileges, TokenPrivileges: TTokenPrivileges; 
      ReturnLength: dword; 
      hToken: THandle; 
      Luid: int64; 
      Hfrm : THandle;
    begin
      Retlppe := GetProcessID('zzllk.exe');
      PID:=Retlppe.th32ProcessID;  //得到进程ID
      hProcess := OpenProcess(PROCESS_ALL_ACCESS, False,PID);   //得到句柄
      Hfrm := GetHWndByPID(hProcess);
    end;
    需要改正一下代碼:    function EnumWindowsProc(Wnd: DWORD; var EI: TEnumInfo): Bool; stdcall;
        var
          PID: DWORD;
        begin
          GetWindowThreadProcessID(Wnd, @PID);
          if (PID = EI.ProcessID) and IsWindowVisible(Wnd) and IsWindowEnabled(Wnd) then
          begin //確保不要取到隱藏或不可輸入的窗口
            Result := False;
            EI.HWND := WND;   
          end;
        end;
      

  12.   

    刚测试了仙女的源码,可以正常找到窗口句柄,成功了!!!!感谢仙女
    Avan_Lau你让我改的那个源码,然后怎么放到BUTTON1的单击事件里呢?
      

  13.   

    奇怪,为什么得到的值是 0 ?  
    前辈请看源码
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ExtCtrls,TLHelp32;type
      TForm1 = class(TForm)
        Button1: TButton;
        Edit1: TEdit;
        Label1: TLabel;
        Label2: TLabel;
        Edit2: TEdit;
        Edit3: TEdit;
        Button2: TButton;
        procedure Button1Click(Sender: TObject);
       function GetHWndByPID(const hPID: THandle):THandle;
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;
    implementation{$R *.dfm}
    function GetProcessID(ProcessName:string):TProcessEntry32;
    var
      lppe: TProcessEntry32;
      found : boolean;
      Hand : THandle;
      P:DWORD;
      s:string;begin
      FillChar(result,SizeOf(TProcessEntry32),0);
      Hand := CreateToolhelp32Snapshot(TH32CS_SNAPALL,0);
      lppe.dwSize := Sizeof(lppe);  while found do
      begin
        s := string(lppe.szExeFile);
        if lppe.th32ProcessID>0 then
          p := lppe.th32ProcessID
        else
          p := 0;
        if UpperCase(ExtractFileName(s))=UpperCase(ExtractFileName(ProcessName)) then
        begin
          GetProcessID:=lppe;
          break;
        end;
        found := Process32Next(Hand,lppe);
      end;
    end;
    procedure TForm1.Button1Click(Sender: TObject);
    var
    Retlppe:TProcessEntry32;
    s,x:integer  ;
    hProcess: THandle;
    PID:DWORD;
    vNumberOfBytesWritten: DWORD;
    OldTokenPrivileges, TokenPrivileges: TTokenPrivileges;
    ReturnLength: dword;
    hToken: THandle;
    Luid: int64;
    Hfrm : THandle;
    begin
    Retlppe := GetProcessID('zzllk.exe');
    PID:=Retlppe.th32ProcessID;  //得到进程ID
    hProcess := OpenProcess(PROCESS_ALL_ACCESS, False,PID);   //得到句柄
    Hfrm := GetHWndByPID(hProcess);
    edit3.text := inttostr(Hfrm);end;function TForm1.GetHWndByPID(const hPID: THandle): THandle;
    type
        PEnumInfo = ^TEnumInfo;
        TEnumInfo = record
        ProcessID: DWORD;
        HWND: THandle;
        end;    function EnumWindowsProc(Wnd: DWORD; var EI: TEnumInfo): Bool; stdcall;
        var
        PID: DWORD;
        begin
        GetWindowThreadProcessID(Wnd, @PID);
          if (PID = EI.ProcessID)and IsWindowVisible(Wnd) and IsWindowEnabled(Wnd) then      begin  //確保不要取到隱藏或不可輸入的窗口
            Result := False;
            EI.HWND := WND;   
          end;
        end;    function FindMainWindow(PID: DWORD): DWORD;
        var
        EI: TEnumInfo;
        begin
        EI.ProcessID := PID;
        EI.HWND := 0;
        EnumWindows(@EnumWindowsProc, Integer(@EI));
        Result := EI.HWND;
        end;
    begin
        if hPID<>0 then
        Result:=FindMainWindow(hPID)
        else
        Result:=0;
        
    end;
    end.
      

  14.   

    edit3.text := inttostr(Hfrm);
      

  15.   


    function GetProcessID(ProcessName:string):TProcessEntry32;
    var
      lppe: TProcessEntry32;
      found : boolean;
      Hand : THandle;
      P:DWORD;
      s:string;begin
      FillChar(result,SizeOf(TProcessEntry32),0);
      Hand := CreateToolhelp32Snapshot(TH32CS_SNAPALL,0);
      lppe.dwSize := Sizeof(lppe);  while found do
      begin
        s := string(lppe.szExeFile);
        if lppe.th32ProcessID>0 then
          p := lppe.th32ProcessID
        else
          p := 0;
        if UpperCase(ExtractFileName(s))=UpperCase(ExtractFileName(ProcessName)) then
        begin
          GetProcessID:=lppe;
          break;
        end;
        found := Process32Next(Hand,lppe);
      end;
    end;
    你这里的while循环会进去么? 
      

  16.   

    function GetProcessID(ProcessName:string):TProcessEntry32;
    var
      lppe: TProcessEntry32;
      found : boolean;
      Hand : THandle;
      P:DWORD;
      s:string;begin
      FillChar(result,SizeOf(TProcessEntry32),0);
      Hand := CreateToolhelp32Snapshot(TH32CS_SNAPALL,0);
      lppe.dwSize := Sizeof(lppe);
      found := Process32First(Hand,lppe);//加上这句
      while found do
      begin
        s := string(lppe.szExeFile);
        if lppe.th32ProcessID>0 then
          p := lppe.th32ProcessID
        else
          p := 0;
        if UpperCase(ExtractFileName(s))=UpperCase(ExtractFileName(ProcessName)) then
        begin
          GetProcessID:=lppe;
          break;
        end;
        found := Process32Next(Hand,lppe);
      end;
    end;
      

  17.   

    function GetProcessID(ProcessName:string):TProcessEntry32;
    var
      lppe: TProcessEntry32;
      found : boolean;
      Hand : THandle;
      P:DWORD;
      s:string;begin
      FillChar(result,SizeOf(TProcessEntry32),0);
      Hand := CreateToolhelp32Snapshot(TH32CS_SNAPALL,0);
      lppe.dwSize := Sizeof(lppe);
      found := Process32First(Hand,lppe);//****************加上这句
      while found do
      begin
        s := string(lppe.szExeFile);
        if lppe.th32ProcessID>0 then
          p := lppe.th32ProcessID
        else
          p := 0;
        if UpperCase(ExtractFileName(s))=UpperCase(ExtractFileName(ProcessName)) then
        begin
          GetProcessID:=lppe;
          break;
        end;
        found := Process32Next(Hand,lppe);
      end;
    end;
      

  18.   

    把IsWindowVisible(Wnd) 和 IsWindowEnabled(WNd)這兩個判斷拿掉看看,照理說,這兩個條件是滿足的才是...
      

  19.   

    to kfcoffe  已经加上了
    to Avan_lau  这两个判断去掉了结果还是0,我确定,进程句柄可以得到,窗口句柄还是0
    请前辈看
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ExtCtrls,TLHelp32;type
      TForm1 = class(TForm)
        Button1: TButton;
        Edit1: TEdit;
        Label1: TLabel;
        Label2: TLabel;
        Edit2: TEdit;
        Edit3: TEdit;
        Button2: TButton;
        procedure Button1Click(Sender: TObject);
       function GetHWndByPID(const hPID: THandle):THandle;
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;
    implementation{$R *.dfm}
    function GetProcessID(ProcessName:string):TProcessEntry32;
    var
      lppe: TProcessEntry32;
      found : boolean;
      Hand : THandle;
      P:DWORD;
      s:string;begin
      FillChar(result,SizeOf(TProcessEntry32),0);
      Hand := CreateToolhelp32Snapshot(TH32CS_SNAPALL,0);
      lppe.dwSize := Sizeof(lppe);
      found := Process32First(Hand,lppe);//加上了
      while found do
      begin
        s := string(lppe.szExeFile);
        if lppe.th32ProcessID>0 then
          p := lppe.th32ProcessID
        else
          p := 0;
        if UpperCase(ExtractFileName(s))=UpperCase(ExtractFileName(ProcessName)) then
        begin
          GetProcessID:=lppe;
          break;
        end;
        found := Process32Next(Hand,lppe);
      end;
    end;
    procedure TForm1.Button1Click(Sender: TObject);
    var
    Retlppe:TProcessEntry32;
    s,x:integer  ;
    hProcess: THandle;
    PID:DWORD;
    vNumberOfBytesWritten: DWORD;
    OldTokenPrivileges, TokenPrivileges: TTokenPrivileges;
    ReturnLength: dword;
    hToken: THandle;
    Luid: int64;
    Hfrm : THandle;
    begin
    Retlppe := GetProcessID('zzllk.exe');
    PID:=Retlppe.th32ProcessID;  //得到进程ID
    hProcess := OpenProcess(PROCESS_ALL_ACCESS, False,PID);   //得到句柄
    edit1.Text := inttostr(hProcess);
    Hfrm := GetHWndByPID(hProcess);
    edit3.text := inttostr(Hfrm);end;function TForm1.GetHWndByPID(const hPID: THandle): THandle;
    type
        PEnumInfo = ^TEnumInfo;
        TEnumInfo = record
        ProcessID: DWORD;
        HWND: THandle;
        end;    function EnumWindowsProc(Wnd: DWORD; var EI: TEnumInfo): Bool; stdcall;
        var
        PID: DWORD;
        begin
        GetWindowThreadProcessID(Wnd, @PID);
          if PID = EI.ProcessID//and IsWindowVisible(Wnd) and IsWindowEnabled(Wnd) then
          then
          begin  //確保不要取到隱藏或不可輸入的窗口
            Result := False;
            EI.HWND := WND;   
          end;
        end;    function FindMainWindow(PID: DWORD): DWORD;
        var
        EI: TEnumInfo;
        begin
        EI.ProcessID := PID;
        EI.HWND := 0;
        EnumWindows(@EnumWindowsProc, Integer(@EI));
        Result := EI.HWND;
        end;
    begin
        if hPID<>0 then
        Result:=FindMainWindow(hPID)
        else
        Result:=0;end;
    end.
      

  20.   

    //and IsWindowVisible(Wnd) and IsWindowEnabled(Wnd) then这里我加了//  变成了注释  已经去掉了
      

  21.   


     function EnumWindowsProc(Wnd: DWORD; var EI: TEnumInfo): Bool; stdcall;
        var
        PID: DWORD;
        begin
          Result := True;          // .............加上试试.........
          GetWindowThreadProcessID(Wnd, @PID);
          if PID = EI.ProcessID//and IsWindowVisible(Wnd) and IsWindowEnabled(Wnd) then
          then
          begin  //確保不要取到隱藏或不可輸入的窗口
            Result := False;
            EI.HWND := WND;   
          end;
        end;
      

  22.   

    參數傳錯了
    Hfrm := GetHWndByPID(Retlppe.th32ProcessID);
      

  23.   

    前辈,确实可以读到窗口句柄,但是程序最小化后就读的不准确了不知道为什么?我刚把那2个判断又加上去了,还是读的不准确?
    IsWindowVisible(Wnd) 和 IsWindowEnabled(WNd)刚加上去了
      

  24.   

    就剩90分了.
    一共190分吧http://topic.csdn.net/u/20100203/17/e3bbdf40-59bc-4f0f-bd0d-993bd2ea0c0d.html
    这个贴的地址.求解决..最小化后就不能根据进程句柄得到准确的窗口句柄该如何解决?
      

  25.   

    IsWindowVisible不要加了,因為最小化時,是設定windowstate,最終調用API:SHowWindow來隱藏。那么最小化時,他讀到的應該是那個看不見(沒有高度和寬度)的窗口,比如application.createhandle創建的。
      

  26.   

    已经把IsWindowVisible比如说正确的窗口句柄是  313131而加上IsWindowVisible读的是  212121去掉IsWindowVisible读的是  151515反正最小化后读的就不准确..源码如下unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ExtCtrls,TLHelp32;type
      TForm1 = class(TForm)
        Button1: TButton;
        Edit1: TEdit;
        Label1: TLabel;
        Label2: TLabel;
        Edit2: TEdit;
        Edit3: TEdit;
        Button2: TButton;
        procedure Button1Click(Sender: TObject);
       function GetHWndByPID(const hPID: THandle):THandle;
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;
    implementation{$R *.dfm}
    function GetProcessID(ProcessName:string):TProcessEntry32;
    var
      lppe: TProcessEntry32;
      found : boolean;
      Hand : THandle;
      P:DWORD;
      s:string;begin
      FillChar(result,SizeOf(TProcessEntry32),0);
      Hand := CreateToolhelp32Snapshot(TH32CS_SNAPALL,0);
      lppe.dwSize := Sizeof(lppe);
      found := Process32First(Hand,lppe);//加上了
      while found do
      begin
        s := string(lppe.szExeFile);
        if lppe.th32ProcessID>0 then
          p := lppe.th32ProcessID
        else
          p := 0;
        if UpperCase(ExtractFileName(s))=UpperCase(ExtractFileName(ProcessName)) then
        begin
          GetProcessID:=lppe;
          break;
        end;
        found := Process32Next(Hand,lppe);
      end;
    end;
    procedure TForm1.Button1Click(Sender: TObject);
    var
    Retlppe:TProcessEntry32;
    s,x:integer  ;
    hProcess: THandle;
    PID:DWORD;
    vNumberOfBytesWritten: DWORD;
    OldTokenPrivileges, TokenPrivileges: TTokenPrivileges;
    ReturnLength: dword;
    hToken: THandle;
    Luid: int64;
    Hfrm : THandle;
    begin
    Retlppe := GetProcessID('LeapFTP.exe');
    PID:=Retlppe.th32ProcessID;  //得到进程ID
    hProcess := OpenProcess(PROCESS_ALL_ACCESS, False,PID);   //得到句柄
    edit1.Text := inttostr(hProcess);
    Hfrm := GetHWndByPID(Retlppe.th32ProcessID);
    edit3.text := inttostr(Hfrm);end;function TForm1.GetHWndByPID(const hPID: THandle): THandle;
    type
        PEnumInfo = ^TEnumInfo;
        TEnumInfo = record
        ProcessID: DWORD;
        HWND: THandle;
        end;    function EnumWindowsProc(Wnd: DWORD; var EI: TEnumInfo): Bool; stdcall;
        var
        PID: DWORD;
        begin    GetWindowThreadProcessID(Wnd, @PID);
          if (PID = EI.ProcessID) //////////////and IsWindowVisible(Wnd) and IsWindowEnabled(Wnd) then
          then
          begin  //確保不要取到隱藏或不可輸入的窗口
            Result := False;
            EI.HWND := WND;
          end;
        end;    function FindMainWindow(PID: DWORD): DWORD;
        var
        EI: TEnumInfo;
        begin
        EI.ProcessID := PID;
        EI.HWND := 0;
        EnumWindows(@EnumWindowsProc, Integer(@EI));
        Result := EI.HWND;
        end;
    begin
        if hPID<>0 then
        Result:=FindMainWindow(hPID)
        else
        Result:=0;end;
    end.