有一个外部程序,表面上看就是一个普通的程序,但是用工具软件分析它的结构,却发现是个MDI程序,但是它的子窗体是直接显示在Client区域的,无法单独关闭,也不知道子窗体的标题。请问这样的程序,怎么获取子窗体的句柄呢?该子窗体中包含一个panel控件,我是想获取这个panel的句柄。还请朋友们多多赐教!

解决方案 »

  1.   

    另外还有两个小问题:
    1,如果外部程序是用VC或者C++builder之类的软件所写的,那可以正常获取控件的句柄么?
    2,如果外部程序用了加壳工具进行加壳,请问在未脱壳的情况下,可以正常通过句柄获取edit类的值么?谢谢!
      

  2.   

    首先在主程序里找一个类名叫MDIClient的窗体,这个是所有MDI窗体的容器。然后再以这个句柄为父句柄,找下面的MDI子窗体,可用FindWindowEx
      

  3.   

    SPY++应该可以看到子窗体的标题?
      

  4.   

    自己顶一下,如果MDI程序的子窗体中有个panel,需要获取该panel上的label的值,不知道应该怎么改动程序。另外如果程序已经被加壳,是否还能获取所需的内容?还希望Zswang老师能来解答一下。
      

  5.   

    你可以用wnd:=FindWindowEx(......)获取一个子窗口,
    然后不停的用wnd:=GetWindow(wnd,GW_HWNDNEXT);来得到所有子窗口
    获得子窗口的控件句柄也简单,wnd:=GetWindow(wnd,GW_CHILD);注意第二个参数
    得到一个子句柄之后,就可以继续用GW_HWNDNEXT很YD地得到其他子窗口上控件的句柄了
    大部分加壳不影响句柄,只有1%不到的壳会影响吧!
      

  6.   

    這是我前段時間寫的,你看下吧。
    function TForm1.GetHandle: integer;
    var
    hD : hwnd;
    buffer:   array[0..254] of char;
    begin
    FillChar(buffer,254,#0);
    hd := FindWindow('Tform1',nil);
    hd := FindWindowEx(hd,0,'MDIClient',nil);
    Result := FindWindowEx(hd,0,'TForm2',nil);
    end;
    另附: WM_CopyDataprocedure TForm5.Button1Click(Sender: TObject);
    var
    cds: TCOPYDATASTRUCT;
    s:string;
    vHandle:THandle;
    begin
    vHandle:=FindWindow('TForm123',nil); //寻找MDI主窗体
    vHandle:=FindWindowEx(vHandle,0,'MDIClient',nil);//寻找MDI容器区域
    vHandle:=FindWindowEx(vHandle,0,'TForm2',nil);//寻找MDI子窗体
    s:='消息测试';
    cds.dwData := 1;
    cds.cbData := Length(S) + 1;
    cds.lpData := nil;
    GetMem(cds.lpData, cds.cbData); //为传递的数据区分配内存 
    try
        if cds.lpData <> nil then
        begin
          try
            StrCopy(cds.lpData, PChar(S));
            Windows.SendMessage(vHandle, WM_COPYDATA, 0, integer(@cds));
          except
          end;
        end;
    finally
        if cds.lpData <> nil then
        begin
          FreeMem(cds.lpData); //释放资源end;
        end;
    end;
    end;
      

  7.   

    谢谢骑士和华哥的解答。事实上,我获取的MDI子窗体的句柄应该是正确的,因为我另外还用spy++试过,句柄和我获取的是相同的,只是在用dll跨进程获取数据时,出现问题,任何数据都获取不了。而同样的代码,如果是用来获取普通外部程序(非MDI),则可以正常获取数据。所以我想,MDI程序是否跟普通程序有哪些不同之处。华哥的这段代码跟原来的代码比较接近,等会我再看看有什么不同的,谢谢你了。这是我在研究Zswang老师的《跨进程访问VCL》出现的问题,因为Zswang老师的那个程序是在资源区需要5个资源分才能下载的,所以我在没有得到Zswang老师的许可前,不方便贴代码出来。不知道有谁研究过这个程序的,希望能得到具体的指点,或者大致解答一下MDI程序操作上的区别就行。如果能得到Zswang老师的亲口解答,那是最好的了。顺便说一下那个资源区的下载,其实只要在下载后回一下帖,就可以把下载所费的资源分全部拿回来,甚至还会多赚一分(汗),不知道是不是BUG。希望能有懂行的朋友帮我解答一下,或者有兴趣的朋友可以互相交流,谢谢了