枚举对话框或FormView中的控件

介绍 再一次,一个项目我正在呼吁一个特性(或特征,如果你喜欢这个词更好)我从来没有实现——定心表单中的控件视图,同时保持彼此之间的相对位置。 为了节省时间,我的第一站是在CodeProject上看看别人做过我。想象我惊讶的是当我发现没有在这个网站上,甚至在MSDN做这样的事情。我的搜索不是我称之为详尽的,但我花了大约30分钟寻找一些能够达到我的目的。我发现了什么?没有什么结果。零。无价值之物。一个老式的鹅蛋。 所以我在这里再次迫使你忍受我的生物,这样我可能会传播一些知识在你寻找执行此功能的代码。nit的拾荒者,我甚至包括一个示例的源代码项目。 它是如何工作的 我们的项目是一个SDI kiosk-style应用程序,它是全屏幕没有Titlebar,菜单、工具栏、状态栏。它还隐藏任务栏。用户被迫离开屏幕,屏幕没有偏离他的路径。从本质上讲,每个屏幕上都是一个不同的CFormView一组不同的控制在每个页面。我们不确定的一件事就是屏幕分辨率的工作站配置。 要解决这个问题,我们只是使用的对话框模板创建表单视图尺寸我们需要的任何东西,然后写一些代码来中心整个过程视图显示的时候。为了做到这一点,我们需要能够移动每个控件,不管有多少有或者他们的ID(是的,每个有不同的控制形式,所以这个方面是一个必做的)。 幸运的是,Windows API函数做我们需要做的。我们需要做的是通过子窗口的形式列举的观点。 酷的是,一旦你控制的hWnd,您可以回复到MFC和操纵控制自己(包括数据)。这是代码的肉,都是需要通过枚举所有的视图(或对话框的)控制:隐藏,复制Code

// get the top-most window in the 
// chain of child windows
HWND hwnd = ::GetTopWindow(this->GetSafeHwnd());
// while we have a valid hwnd, 
// loop through all child windows
while (hwnd)
{
    // do something with the hwnd
    // and get the next child control's hwnd
    hwnd = ::GetNextWindow(hwnd, GW_HWNDNEXT);
}

本文提供的示例应用程序做一些事情在这个while循环,将锚架,改变了文本在一个静态的字符串和重新居中控制每次窗口调整大小。隐藏,收缩,复制Code

HWND hwnd = ::GetTopWindow(this->GetSafeHwnd());
while (hwnd)
{
    // you can even get the ID of the dialog 
    // control you're moving in order 
    // to perform special processing
    UINT nID = ::GetDlgCtrlID(hwnd);
    // if the anchor frame is visible, 
    // hide it, or if not, show it
    if (nID == nAnchorID)
    {
        GetDlgItem(nID)->ShowWindow(GetDlgItem(nID)->
                   IsWindowVisible()?SW_HIDE:SW_SHOW);
    }
    // change the text to all upper case and all 
    // lower case, depending on current state
    else if (nID == IDC_UPLOW_CASE)
    {
        CString sText;
        GetDlgItem(nID)->GetWindowText(sText);
        sText = (sText == "all lowercase") ? 
               "ALL UPPERCASE" : "all lowercase";
        SetDlgItemText(nID, (LPCTSTR)sText);
    }

    // move the window to it's new position
    CRect rect;
    ::GetWindowRect(hwnd, &rect);
    ScreenToClient(&rect);
    ::MoveWindow(hwnd, rect.left + nXDiff, 
          rect.top + nYDiff, rect.Width(), 
          rect.Height(), TRUE);
    // get the next window in the chain
    hwnd = ::GetNextWindow(hwnd, GW_HWNDNEXT);
} // while (hwnd)

切——定心代码 定心代码时不应该真正的本文的重点,我想简要描述它,因为我已经输入像一个疯子。我做的第一件事是创建一个故意小模板,然后创建一个静态框架模板的边缘。这种控制是我的锚,是formview将使用作为参考,将所有其他的控件。 formview使用锚架计算帧移动多远为了保持本身为中心的窗口调整大小。这是至关重要的转移函数。一旦锚架的新x / y位置确定,我列举控制表单的视图和每一个位置偏移量计算。 结果是,将集中控制,只要大于原始模板的窗口。如果视图小于模板,模板将显示滚动条,将定位在这样一种方式,面向前/父窗口的左上角。 有趣的发现和警告 是完全合乎逻辑的假设触发转移代码最好从内部实现OnSize()。然而,当我这么做的时候,我发现即使在等待hWnd有效之后,我收到了一个绘图用的矩形类,本质上是一个零矩形(绘图用的矩形类(0,0,0,0))。我发现,虽然初始化一个MFC SDI应用程序,视图的OnSize()方法的四倍! 第四次是在调用之后OnInitialUpdate(),所以我把一个bool变量(m_bCanBeRelocated和在构造函数中设置为false)的类,然后设置为true OnInitialUpdate年底()。在这一点上,你可以放心,你会得到有效的矩形信息当你叫GetClientRect()。 视图大小小于模板时,滚动条会显示为预期。然而,如果你滚动滚动条,然后再调整(同时保持视图小于模板),控件会错误地定位,这样被部分左和/或顶部的观点。 为了解决这个问题,我只是叫SetScrollPos()位置照片卷轴(0,0。我知道这是一个黑客的变通办法,但是它解决了问题,这篇文章并不是关于定心代码。 最后的话 如果你要这篇文章投票,离开你的国内政治,作为一个成年人,投票文章的优点。这是不公平的我啊如果你只是因为不同意我的政治观点,就扯些幼稚的投票废话,那就会被其他人嘲笑。如果您想谈论政治,我们可以在CodeProject的soapbox论坛上占用您所需要的空间。 本文转载于:http://www.diyabc.com/frontweb/news8135.html

posted @ 2020-08-10 08:10  Dincat  阅读(192)  评论(0编辑  收藏  举报