嵌套面板不按预期滚动。为什么不呢?

时间:2017-06-20 18:35:45

标签: c++ winapi scroll

我正在使用C ++和winapi创建GUI。我已经能够计算出很多细节,但是我在另一个面板中滚动面板时遇到了一些麻烦。我知道如何在c#中执行此操作,但是使用c ++我失败了。

enter image description here

我创建了一个类,它为一个通用的“主题”生成一个面板,我可以指定主题的名称(例如,“主题A”)。我创建了一个单独的类,它生成一个Panel来包含所有这些主题。那是TopicHolder。所以我传入一个名称为字符串的向量。然后我生成新的Topic对象,每个对象都有自己的GUI控件。然后我更新了TopicHolder的布局,包括所有主题,根据标准尺寸为它们提供x和y位置。

一切看起来或多或少都像我最初想要的那样。如果这是c#,主题持有者将滚动并且各种主题将滚动进出视线,具体取决于可见的较大面板的确切部分。然而,在这种情况下,滚动对absolutley没有影响。这是我第一次使用滚动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

2 个答案:

答案 0 :(得分:0)

y中主题的UpdateLayout位置始终保持为5,因此不会发生滚动。您应保留一些偏移值并在上下滚动时更改它,以便y从此偏移量开始。

答案 1 :(得分: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.