同时移动多个Windows [英] Move Multiple Windows Simultaneously

查看:45
本文介绍了同时移动多个Windows的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在此处重新发布我的问题来自Stack Overflow 以获得更多曝光。







我需要同时移动几个外部应用程序窗口(一起)作为一组进行模拟滚动功能。



如果你的第一个想法是你为什么要那样做或你永远不应该那样做,那就假装这是一个好主意,会很棒。



到目前为止,我已经尝试了PInvoke方法MoveWindow,SetWindowPos和(BeginDeferWindowPos,DeferWindowPos,EndDeferWindowPos)。



所有这些方法产生的性能大致相同。移动一个窗口是超级活泼的,两个窗口没什么大不了的,但是一旦我尝试移动三个或更多的窗户,事情开始变得难看。这是一个使用延迟方法的片段,向您展示我是如何做事并跟踪性能的。

I am re-posting my question from Stack Overflow here for more exposure.



I need to move several external application windows at the same time (together) as a group to simulate scrolling functionality.

If your first thought is "why would you want to do that" or "you should never do that", just pretend that it's a good idea and would be fantastic.

So far I have tried the PInvoke methods MoveWindow, SetWindowPos, and (BeginDeferWindowPos, DeferWindowPos, EndDeferWindowPos).

All of these methods produce about the same performance. Moving one window is super snappy, two windows is no big deal, but once I try to move three or more windows things start to get ugly. Here is a snippet using the deferred method to show you how I am doing things and keeping track of performance.

private void multiMoveWindows(int moveAmt, int startingIndex)
{
    int tempX;
    int howmanyTimes = 0;
    int numOfWidgetsToMove = 0;
    int moveAmtRemaining = moveAmt;
    IntPtr MultiWindowStructure;
    System.Diagnostics.Stopwatch t = new Stopwatch();            
    WidgetTracker[] tmp_WhichWidgets = new WidgetTracker[10];           

    foreach (KeyValuePair<string, WidgetTracker> entry in m_dictWT)
    {
        WidgetTracker tmp = new WidgetTracker();
        tmp = entry.Value;
        if (tmp.WIndex >= startingIndex)
        {
            tmp_WhichWidgets[numOfWidgetsToMove] = tmp;
            ++numOfWidgetsToMove;
        }
    }

    for (int i = 0; i < moveAmtRemaining; i++)  
    {
    MultiWindowStructure = Native_Methods.BeginDeferWindowPos(numOfWidgetsToMove);
        foreach (WidgetTracker tmp in tmp_WhichWidgets)
        {
            if (tmp != null)
            {
                tmp.surveilWidget();
                tempX = tmp.WidgetRectLeft - 1;                    
                MultiWindowStructure = Native_Methods.DeferWindowPos(
                    MultiWindowStructure, tmp.WidgetHandle, HWND.NOTOPMOST, tempX, tmp.WidgetRectTop, tmp.WidgetWidth, tmp.WidgetHeight, SWP.NOREDRAW);
                howmanyTimes++;
            }
        }
        t.Start();
        Native_Methods.EndDeferWindowPos(MultiWindowStructure);
        t.Stop();             
    }
    MessageBox.Show(howmanyTimes.ToString() + " move requests made." + Environment.NewLine + 
        "Execution of EndDeferWindowPos took " + t.Elapsed.Seconds.ToString() + " sec " + t.Elapsed.Milliseconds.ToString() + " ms." );    
}







移动4个窗口,320px左移,1px一次的结果?

>在14.445秒内发出1280次移动请求。



你可以想象,等待14.5秒才能看到4个窗口穿过屏幕320像素是很难看的。 br />
- 如何以流畅的方式实现这一目标?



是的,我意识到我一次可以移动超过1px,但是这不会解决根本问题。我理解它的方式,使用任何PInvoke方法移动窗口将消息发布到WinAPI消息泵(WndProc())并在发布下一条消息之前等待消息被关闭/捕获/处理。我认为这是我花费14.5秒的时间 - 等待消息处理。



我尝试过使用SWP ASYNCWINDOWPOS,结果很糟糕。每个窗口只看到几十个看似随意的消息,这样窗户就会重叠,整个火车几乎不会移动。



我最接近的是一个解决方案是为每个窗口小部件分配一个父窗口(例如WindowsFormsHost +一个MDI窗口)并将它们放在窗体/窗口中,然后滚动该窗体/窗口。但是我有几个理由不想这样做。

请帮忙!




The result for moving 4 windows, 320px left, 1px at a time?
> 1280 move requests made in 14.445 sec.

As you can imagine, waiting 14.5 seconds to see 4 windows make their way across the screen 320 pixels is painful to watch.
- How can this be accomplished in a fluid manner?

Yes, I realize that I can move more than 1px at a time, but that won't resolve the underlying issue. The way I understand it, using any of the PInvoke methods to move windows posts messages to the WinAPI message pump (WndProc()) and waits for the message to be closed / caught / handled before posting the next message. I think this is where I am spending that 14.5 seconds - waiting for messages to be handled.

I have tried using SWP ASYNCWINDOWPOS and the result is horrendous. Each window only gets a few dozen of the messages seemingly at random so that windows are overlapping and as a whole the train barely moves.

The closest I've come to a solution is to assign each "widget" a parent (for example a WindowsFormsHost + an MDI window) and putting them in a form/window and then scrolling that form/window. However I have several reasons for not wanting to do that.
Please help!

推荐答案

1。同样的问题Ron Beyer问你:请准确定义外部应用程序窗口。



2.这是一个WindowsForms项目吗?如果没有,那么背景是什么:WPF? ... C ++?



3.是否有一个只有一个窗口,如果移动移动所有其他窗口?如果多个窗口可以移动所有其他窗口,那么你可以进行递归处理。



4.你做了什么尝试并暂停内部刷新窗口由于另一个窗口被移动而被移动?



5.假设只有一个窗口可以被移动并导致其他窗口跟随它:它是一个要求您通过用户与TitleBar的交互来跟踪移动...或者,窗口中的某些操作是否正常:例如,单击拖动某些图形元素,还是在活动窗口区域中单击拖动?



6.您现在使用GlobalHook;如果是这样,代码的来源是什么:CP?
1. same question Ron Beyer asked you: please define 'external application windows' in this context precisely.

2. is this a WindowsForms project ? if not, what's the context: WPF ? ... C++ ?

3. is there one-and-only-one window that if moved moved all others ? if more than one window can move all other windows, then you have possible recursion to deal with.

4. have you done anything to try and suspend internal refresh of windows being moved as a result of another window being moved ?

5. assuming only one Window can be moved and cause the other windows to "follow" it: is it a requirement that you "track" the move by the user's interaction with the TitleBar ... or, is some action in the Window okay: like click-dragging some graphic element, or click-dragging in the active window area ?

6. are you using a GlobalHook now; if so, what's the source of the code: CP ?


这篇关于同时移动多个Windows的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆