列舉對話方塊或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