我想把一个基于对话框的程序绑架到自己的主界面来,写了一个小的测试程序,被绑架窗口上只有按钮的时候用SetParent可以顺利的被设置成我的子窗口,如果被绑架窗口上有树形控件CTreeCtrl的话用SetParent就不起作用了,请问为什么,CTreeCtrl有什么特殊的地方吗?同一个被绑架窗口测试2次,一次有CTreeCtrl,不成功,一次没有CTreeCtrl,成功。

解决方案 »

  1.   

    你SetParent的参数,是怎样获取的?
      

  2.   

    // 枚举窗口获取cmd窗口句柄
    HWND g_hCmdHwnd;  // 创建的CMD进程
    int CALLBACK EnumWindowsProc(HWND hwnd, LPARAM param)
    {
    DWORD pID;
    // 获取进程ID
    DWORD TpID = GetWindowThreadProcessId(hwnd, &pID);
    if (TpID == (DWORD)param)
    {
    g_hCmdHwnd = hwnd; return 0;
    }
    return 1;
    }
    //////以下是绑架部分的代码 HANDLE hProcess = NULL;
    PROCESS_INFORMATION pi;
    STARTUPINFO si;      //隐藏进程窗口
    si.cb = sizeof(STARTUPINFO);
    si.lpReserved = NULL;
    si.lpDesktop = NULL;
    si.lpTitle = NULL;
    si.dwFlags = STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_HIDE;
    si.cbReserved2 = NULL;
    si.lpReserved2 = NULL;
    if(::CreateProcess("D:\\DATA\\test\\ccc\\debug\\ccc.exe","",NULL,NULL,FALSE,0,NULL,NULL,&si,&pi))
    {
    Sleep(1000);
    ::EnumWindows(&EnumWindowsProc, pi.dwThreadId);//Iterate all windows
    }
    if(g_hCmdHwnd!=NULL)
    {
    //绑架它
    ::SetParent(g_hCmdHwnd,m_wndTradeBar.m_hWnd );
    ::ShowWindow(g_hCmdHwnd, SW_SHOW);
    }
    else
    {
    AfxMessageBox("没找到!");
    }
      

  3.   

    肯定可以。
    1. 检查是否枚举到需要被绑架的窗口
    2. SetParent后需要保存并修改被绑架窗口的风格. 添加WS_CHILD.
    3. 脱离绑架前,需要恢复被绑架窗口的风格.
    我做过类似的超级容器,可以绑架任何窗口。
      

  4.   

    请问secretcf,有枚举被绑架窗口的代码吗,我感觉这里出问题的可能性大,SetParent之后我用GetLastError得到的错误码是1400.还有一点比较郁闷的是就上面那些代码,被绑架窗口有CTreeCtrl就失败,没有CTtreeCtrl就成功,有关系吗?给我点枚举窗口的代码吧,谢谢!
      

  5.   

    谢谢上面几位兄弟回复,问题解决了,给分结贴。把枚举的回调函数修改如下就行了。int CALLBACK EnumWindowsProc(HWND hwnd, LPARAM param)
    {
    DWORD pID;
    HWND thwnd;
    // 获取进程ID
    DWORD TpID = GetWindowThreadProcessId(hwnd, &pID);
    if (pID == (DWORD)param)
    {
    while((thwnd=::GetParent (hwnd)) != NULL)
    {
    hwnd=thwnd;
    }
    g_hCmdHwnd = hwnd; return 0;
    }
    return 1;
    }
    主要是找到目标进程的窗口句柄后再来一个循环,以确保找到的是顶层窗口的句柄。