2017-06-20 57 views
0

我正在使用C++和winapi創建一個GUI。我已經能夠制定出很多細節,但是在另一個面板中滾動面板時遇到了一些麻煩。我知道如何在c#中做到這一點,但與c + +我被擊敗。嵌套面板不按預期滾動。爲什麼不?

enter image description here

我已創建的類,其生成面板一個通用的「主題」,我可以指定主題(例如,「主題A」)的名稱。我創建了一個獨立的類,它生成一個包含所有這些主題的面板。這是TopicHolder。所以我傳入一個名稱爲字符串的向量。然後我生成新的Topic對象,每個對象都有自己的GUI控件。然後,我更新TopicHolder的佈局,包括所有主題,根據他們的標準大小爲他們提供x和y位置。

一切看起來或多或少像我最初想要的。如果這是c#,則主題持有者將滾動,並且各個主題將根據可見的較大面板的確切部分滾動進入和看不見。但是,在這種情況下,滾動不起作用。這是我第一次使用C++ gui進行滾動,所以我可能會錯過一些東西。

以下是一些關鍵代碼段。我會歡迎任何有用的提示。 感謝

添加主題

void TopicHolder::SetTopics(std::vector<std::string> t) 
{ 
    for(unsigned i=0;i<t.size();i++) 
    { 
    //I give the topic the HWND of the TopicHolder so it can 
    //be properly parented on that GUI element 
    Topic* tmp = new Topic(myHWND, t[i]); 
    vectorOfTopics.push_back(tmp); 
    } 

    UpdateLayout(holderRect); 
} 

在主題相對佈局的主題來處理TopicHolder

void TopicHolder::UpdateLayout(RECT r) 
{ 
    int buffer = 5;//buffer between elements 
    int x = buffer; 
    int y = buffer; 

    for(unsigned i=0;i<vectorOfTopics.size();i++) 
    { 
    RECT tmp; 
    tmp.left=x; 
    tmp.top=y; 
    tmp.right = r.right-(2*buffer); 
    tmp.bottom = y+Topic::HEIGHT;//standard height per topic 
    vectorOfTopics[i].Layout(tmp); 
    y+= Topic::HEIGHT+buffer; 
    } 
} 

佈局對象

void Topic::Layout(RECT r) 
{ 
    SetWindowPos(myHWND, //this is the HWND of the topic 
    HWND_TOP, r.left, r.top, Topic::WIDTH, Topic::HEIGHT, SWP_SHOWWINDOW); 
} 

---------- - - - - -編輯 - - - - - - - - - - - - - - - - - - - - -

Grr ...好吧,所以C++不支持這個,正如你們許多人所解釋的那樣。我(痛苦地)一直在學習設置我的滾動參數。大多數情況下它按預期工作,但我仍然遇到滾動條的問題。我希望滾動條出現在面板的右側,併爲我的主題面板留下其餘空間。相反,它會略微偏移,並且該區域的其餘部分被繪成淺灰色而不是TopicHolder的背景顏色。現在它只是令人煩惱,但我希望看到它解決。再次,任何幫助將不勝感激。

enter image description here

+0

在Windows API,你是負責處理所有滾動自己;很少有自動支持滾動(有一個函數實際上移動你的窗口和子窗口的像素和函數來操縱滾動條,但就是這樣)。 [Raymond Chen的滾動條系列](http://stackoverflow.com/a/29469939/1889329)是如何進行滾動的實際標準指南。 – andlabs

回答

0

開始在UpdateLayout主題y位置始終保持5,所以沒有滾動發生。你應該保留一些補償值並且如果滾動上下發生變化,所以y將從該補償開始。

+0

對不起,這是不正確的。 y值在循環結束時更新,以便爲每個主題添加行。我可能會改變初始位置來執行滾動,如果我這樣做了,我可能沒有滾動條。我想要的是一個滾動條,導致這個動作自動發生。 – BSD

+0

我測試了你的解決方案,它的工作原理。通過設置一個變量來跟蹤我想要的滾動,我可以改變主題面板的位置。不過,我想讓滾動條自動執行此操作。我從ListView中得到那種我選擇各種主題的行爲,但是這個面板沒有按預期工作。 – BSD

+0

ListView本身就是這樣做的。如果你想在你自己的自定義類中使用這個功能,你自己也必須這樣做。看到我上面的評論。 – andlabs

0

您需要致電SetScrollPos()更改滾動位置或窗口內容。

即:

// hwnd is your control window, SB_VERT refers to its verti8cal scrollbar. 
SetScrollPos(hwnd, SB_VERT, topicHeight * topicToBringToTop, TRUE); 

InvalidateRect(hwnd, NULL, TRUE); // redraw the control. 
+0

嗯。首先,這是以編程方式設置滾動位置,我希望它通過GUI進行正常調整。即便如此,我嘗試了它,結果很奇怪。 GUI不會改變。我爲兩個不同的值運行SetScrollPos,並根據我看到的文檔返回0(初始位置),然後返回我設置的第一個值。所以它正在設置,但我沒有看到任何主題或滾動條的變化。抱歉。 – BSD

+0

@BSD如果你的控件不是一個列表框。您將不得不通過捕獲滾動消息來跟蹤滾動位置,並在WM_PAINT中考慮這一點。由於您的控件是一個列表,因此使用自定義繪圖列表可以從一開始就避免這類問題。 –