MFC窗体中打开第三方exe程序到指定区域

流程如下:

1、CreateProcess创建外部EXE进程

2、获取指定区域的坐标

3、查找进程的主窗口

4、将外部程序移到指定区域

5、调用ShowWindow显示窗口


主程序如下:

handle=StartProcess("D:\\program tool\\SecureCRTPortable\\App\\SecureCRT\\SecureCRT.exe","");

	UpdateData(TRUE);  
    HWND hwnd = NULL;
	CRect rc;
	//GetDlgItem(IDC_CRT)->GetClientRect(&rc);
	GetDlgItem(IDC_CRT)->GetWindowRect(&rc);
	int nWidth = rc.Width();
	int nHeight = rc.Height();
	ScreenToClient(rc);

	while(!hwnd)
	{		
		hwnd =::FindWindow("VanDyke Software - SecureCRT","not connected - SecureCRT");
	}
	if( hwnd)
    {
        LONG style=GetWindowLong(hwnd,GWL_STYLE);// 14CF 0000
		
		style &=~WS_CAPTION;
		style &=~WS_THICKFRAME;
        //style |=WS_CHILD;
        SetWindowLong(hwnd,GWL_STYLE,style);

		 ::SetParent(hwnd,this->m_hWnd);
		//::MoveWindow(hwnd, rc.left, rc.top, nWidth, nHeight, true); //将外部程序移到自自身窗口里		
	    ::SetWindowPos(hwnd,HWND_TOP, rc.left, rc.top, nWidth, nHeight, SWP_SHOWWINDOW |SWP_HIDEWINDOW );
		// ::BringWindowToTop(hwnd);
		//Invalidate();
		//::UpdateWindow(hwnd);
		::ShowWindow(hwnd,SW_SHOW);
	}


一、启动外部程序

StarProcess函数如下:

HANDLE StartProcess(LPCTSTR program, LPCTSTR args)
{

     HANDLE hProcess = NULL;
     PROCESS_INFORMATION processInfo;
     STARTUPINFO startupInfo;
     ::ZeroMemory(&startupInfo, sizeof(startupInfo));
     startupInfo.cb = sizeof(startupInfo);
     if(::CreateProcess(program, (LPTSTR)args, 
                        NULL,  // process security
                        NULL,  // thread security
                        FALSE, // no inheritance
                        0,     // no startup flags
                        NULL,  // no special environment
                        NULL,  // default startup directory
                        &startupInfo,
                        &processInfo))
     return hProcess;
}

二、获取指定区域的坐标

GetWindowRect(LPRECT lpRect);

函数功能:该函数返回指定窗口的边框矩形的尺寸。该尺寸以相对于屏幕坐标左上角的屏幕坐标给出。如果是对话框的话,获取的实际上就是这个对话框的大小。

注意:这个函数的相对坐标原点分两种情况:
1 窗口还没有初始化完成时:原点是整个窗口的左上角
2 初始化完成后,原点是设备屏幕左上角


GetClientRect( LPRECT lpRect )

函数功能:获取的仅是客户区的矩形,也就是说不包括标题栏,外框等。这样得到的左上角永远是(0,0)。


ScreenToClient() 就是把屏幕坐标系下的RECT坐标转换为客户区坐标系下的RECT坐标,这样左上角就不是(0,0),而是实际的坐标。


三、查找窗口的句柄

函数型:HWND FindWindow(LPCTSTR IpClassName,LPCTSTR IpWindowName);
参数:
IpClassName :指向一个指定了类名的空结束字符串,或一个标识类名字符串的成员的指针。如果该参数为一个成员,则它必须为前次调用theGlobafAddAtom函数产生的全局成员。该成员为16位,必须位于IpClassName的低 16位,高位必须为 0。
IpWindowName:指向一个指定了窗口名(窗口标题)的空结束字符串。如果该参数为空,则为所有窗口全匹配。
返回值:如果函数成功,返回值为具有指定类名和窗口名的窗口句柄;如果函数失败,返回值为NULL。

如何获取这些参数呢,使用 spy++ 工具即可,点击 VS 菜单“工具” - “spy++”,启动 spy++


四、移动到指定区域

函数原型:LONG GetWindowLong(HWND hWnd,int nlndex);   

函数功能:该函数获得有关指定窗口的信息,函数也获得在额外窗口内存中指定偏移位地址的32位度整型值。
  
参数:
hWnd:窗口句柄及间接给出的窗口所属的窗口类。
nlndex:指定要检索的基于0的的偏移量。有效值的范围从0到窗口额外内存空间的字节数,最小为4。例如,若指定了12位或多于12位的窗体类的额外存储空间,则应设为第三个32位整数的索引位8。要获得任意其他值,指定下列值之一:
  GWL_EXSTYLE;获得扩展窗口风格。
  GWL_STYLE:获得窗口风格。
  GWL_WNDPROC:获得窗口过程的地址,或代表窗口过程的地址的句柄。必须使用GWL_WNDPROC函数调用窗口过程。
  GWL_HINSTANCE:获得应用事例的句柄。
  GWL_HWNDPAAENT:如果父窗口存在,获得父窗口句柄。
  GWL_ID:获得窗口标识。
  GWL_USERDATA:获得与窗口有关的32位值。每一个窗口均有一个由创建该窗口的应用程序使用的32位值。
  在hWnd参数标识了一个对话框时也可用下列值:
  DWL_DLGPROC:获得对话框过程的地址,或一个代表对话框过程的地址的句柄。必须使用函数CallWindowProc来调用对话框过程。
  DWL_MSGRESULT:获得在对话框过程中一个消息处理的返回值。
  DWL_USER:获得应用程序私有的额外信息,例如一个句柄或指针。 

返回值:如果函数成功,返回值是所需的32位值;如果函数失败,返回值是0。若想获得更多错误信息请调用 GetLastError函数。


函数原型:LONG SetWindowLong(HWND hWnd,int nlndex,LONG dwNewLong); 
函数功能:该函数改变指定窗口的属性.函数也将指定的一个32位值设置在窗口的额外存储空间的指定偏移位置。
参数: 

hWnd:窗口句柄及间接给出的窗口所属的类。
nlndex:指定将设定的大于等于0的偏移值。有效值的范围从0到额外类的存储空间的字节数-4:例如若指定了12位或多于12位的额外类存储空间,则应设为第三个32位整数的索引位8。要设置其他任何值,可以指定下面值之一:
        GWL_EXSTYLE:设定一个新的扩展风格。GWL_STYLE:设定一个新的窗口风格。
        GWL_WNDPROC:为窗口过程设定一个新的地址。GWL_ID:设置一个新的窗口标识符。
        GWL_HINSTANCE:设置一个新的应用程序事例句柄。
        GWL_USERDATA:设置与窗口有关的32位值。每一个窗口均有一个由创建该窗口的应用程序使用的32位值。
        当hWnd参数标识了一个对话框时,也可使用下列值:
        DWL_DLGPROC:设置对话框过程的新地址。
        DWL_MSGRESULT:设置在对话框过程中处理的消息的返回值。
  DWL_USER:设置的应用程序私有的新的额外信息,例如一个句柄或指针。
  dwNewLong:指定的替换值。
返回值:如果函数成功,返回值是指定的32位整数的原来的值。如果函数失败,返回值为0。若想获得更多错误信息,请调用GetLastError函数。

BOOL MoveWindow( HWND hWnd,int x, int y, int nWidth, int nHeight,BOOL bRepaint = TRUE);
  第一个表示窗口句柄;
  参数x,y表示窗口的左上角起点
  参数nwidth,nHeight 表示窗口高度和宽度;
  最后一个bRepaint表示是否立即重绘。为true时系统会立即发送WM_PAINT到窗口程序(会调用UpdateWindow()函数),为false时不会发生任何类型的重绘操作。
  MoveWindow会给窗口发送WM_WINDOWPOSCHANGING,WM_WINDOWPOSCHANGED,WM_MOVE,WM_SIZE和WM_NCCALCSIZE消息。

BOOL SetWindowPos(HWND hWnd,const CWnd* pWndInsertAfter, int x, int y,int cx, int cy, UINT nFlags);
  第一个参数是窗口句柄;
  第二个参数是窗口的Z order,就是有多个窗口时,本窗口显示的顺序,最上面或者最下面,可选参数有     

         HWND_BOTTOM,HWND_NOTOPMOST,HWND_TOP,HWND_TOPMOST.

      HWND_BOTTOM:将窗口置于Z序的底部。如果参数hWnd标识了一个顶层窗口,则窗口失去顶级位置,并且被置在其他窗口的底部。
   HWND_NOTOPMOST:将窗口置于所有非顶层窗口之上(即在所有顶层窗口之后)。如果窗口已经是非顶层窗口则该标志不起作用。
   HWND_TOP:将窗口置于Z序的顶部。
   HWND_TOPMOST:将窗口置于所有非顶层窗口之上。即使窗口未被激活窗口也将保持顶级位置。

  接下来四个参数是窗口的位置和尺寸。
  最后一个参数nFlags是窗口显示方式的标志,这个参数很多,可以组合使用,详细如下:
     SWP_ASNCWINDOWPOS:如果调用进程不拥有窗口,系统会向拥有窗口的线程发出需求。这就防止调用线程在其他线程处理需求的时候发生死锁。
  SWP_DEFERERASE:防止产生WM_SYNCPAINT消息。
  SWP_DRAWFRAME:在窗口周围画一个边框(定义在窗口类描述中)。
  SWP_FRAMECHANGED:给窗口发送WM_NCCALCSIZE消息,即使窗口尺寸没有改变也会发送该消息。如果未指定这个标志,只有在改变了窗口尺寸时才发送WM_NCCALCSIZE。
  SWP_HIDEWINDOW;隐藏窗口。
  SWP_NOACTIVATE:不激活窗口。如果未设置标志,则窗口被激活,并被设置到其他最高级窗口或非最高级组的顶部(根据参数hWndlnsertAfter设置)。
  SWP_NOCOPYBITS:清除客户区的所有内容。如果未设置该标志,客户区的有效内容被保存并且在窗口尺寸更新和重定位后拷贝回客户区。
  SWP_NOMOVE:维持当前位置(忽略X和Y参数)。
  SWP_NOOWNERZORDER:不改变z序中的所有者窗口的位置。
  SWP_NOREDRAW:不重画改变的内容。如果设置了这个标志,则不发生任何重画动作。适用于客户区和非客户区(包括标题栏和滚动条)和任何由于窗回移动而露出的父窗口的所有部分。如果设置了这个标志,应用程序必须明确地使窗口无效并重画窗口的任何部分和父窗口需要重画的部分。
  SWP_NOREPOSITION;与SWP_NOOWNERZORDER标志相同。
     SWP_NOSENDCHANGING:防止窗口接收WM_WINDOWPOSCHANGING消息。
  SWP_NOSIZE:维持当前尺寸(忽略cx和Cy参数)。
  SWP_NOZORDER:维持当前Z序(忽略hWndlnsertAfter参数)。
  SWP_SHOWWINDOW:显示窗口。

运行截图:

MFC窗体中打开第三方exe程序到指定区域_第1张图片

你可能感兴趣的:(mfc,指定区域)