C++ 基于图像的水平适合度调整窗口大小时滚动条指迹长度问题

C++ 基于图像的水平适合度调整窗口大小时滚动条指迹长度问题,c++,windows,C++,Windows,为了做到水平最佳拟合,我想减少或增加实际图像宽度到窗口宽度,而不改变实际图像纵横比。而且我还应该根据新的调整大小的图像(窗口调整大小)保持滚动条拇指轨迹的长度。为此,我做了以下计算 int ActualImageWidth = 1000; int ActualImageHeight = 1200; int WindowWidth = 800; int WindowHeight = 500; float resizedPercent;

为了做到水平最佳拟合,我想减少或增加实际图像宽度到窗口宽度,而不改变实际图像纵横比。而且我还应该根据新的调整大小的图像(窗口调整大小)保持滚动条拇指轨迹的长度。为此,我做了以下计算

    int ActualImageWidth = 1000;  
    int ActualImageHeight = 1200;  
    int WindowWidth = 800;  
    int WindowHeight = 500;  
    float resizedPercent;  
为了设置滚动条,在wm_大小事件上,我使用以下代码

 switch(FitType)  
     {  
      case FITHORIZONTAL:  
          //find out whether resize percentage is decrease or increase  
          if(ActualImageWidth > WindowWidth) //resize decreasing  
          {  
              //find out the pecentage of decreased value  
              resizedPercent = WindowWidth/ActualImageWidth;  
          } else //resize increasing  
          {  
              //find out the pecentage of increased value  
              resizedPercent = ActualImageWidth/WindowWidth;  
          }  
          ResizedWidth = iWndwidth;  
          ResizedHeight = ActualImageHeight * resizedPercent;  
          break;  
     }  

我的问题是我无法获得准确的滚动条拇指轨迹,因此我无法滚动图像,直到图像结束。请务必用示例建议正确的逻辑。注意:如果您以@o_weisman开始评论,我将收到有关我的评论的通知。在我的代码中,我也像这样重写了OnVScroll,它对我很有用(您需要调整它以处理窗口的滚动消息:

LRESULT CALLBACK my_wnd_proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)  
      {  
          static SCROLLINFO si;  
          static RECT rect;  
          int WndWidth = 0;  
          int WndHeight = 0;  
          case WM_CREATE :  
              {  
                  //getting image data from here.  
                  return 0;  
              }  
          case WM_SIZE :  
              {  
                  GetWindowRect(hWnd, &rect);  
                  WndWidth = rect.right - rect.left;  
                  WndHeight = rect.bottom - rect.top;  
                  GetScrollInfo(hWnd, SB_VERT, &si);  
                  int yMaxScroll = max((int)ResizedHeight - WndHeight, 0);  
                  int yCurrentScroll = min(si.nPos, yMaxScroll);  
                  si.cbSize = sizeof(si);  
                  si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;  
                  si.nMin  = 0;  
                  si.nMax  = ResizedHeight;  
                  si.nPage = WndHeight;  
                  si.nPos  = 0;  
                  SetScrollInfo(hWnd, SB_VERT, &si, TRUE);  
                  InvalidateRect(hWnd, &rect, true);  
                  return 0;  
              }  
          case WM_PAINT :  
              {  
                  //try to draw image here..  
                  return 0;  
              }          
      }  
void CMagDialog::OnVScroll(UINT nSBCode、UINT npo、CScrollBar*pScrollBar)
{
内恩德尔塔;
int nMaxPos=ymaxcroll;
如果(pScrollBar==NULL)
{
交换机(nSBCode)
{
案例SB_系列:
如果(m_vScrollPos>=nMaxPos)
返回;
nDelta=min(nMaxPos/100,nMaxPos-m_vScrollPos);
打破
案例SB_阵容:
if(m_vScrollPos=nMaxPos)
返回;
nDelta=min(nMaxPos/5,nMaxPos-m_vScrollPos);
打破
案例SB_位置:
nDelta=(int)nPos-m_vScrollPos;
打破
案例SB_页面:

如果(m_vScrollPos请有人向我建议一些处理的逻辑。拇指大小由nPage设置。请注意,当您恢复位置时,必须补偿拇指大小,因为它有两个侧面。当我以水平配合方式查看图像,调整窗口大小并滚动图像时..我无法滚动到图像末尾..有什么问题吗你在这里。。我不知道如何继续。请有人建议我如何继续。无论是在调整大小还是在滚动条中。@user3034661水平适合是什么意思?你有两个滚动条,一个垂直,一个水平吗?如果是这样的话,我看不到你对水平滚动执行的计算与你对水平滚动的计算相同垂直。如果不是这样,我认为您需要更好地解释您的问题。例如:如果我的图像宽度和高度为1600x2000,客户端窗口宽度和高度为900x600。现在我希望水平调整图像。为此,我将图像宽度(1600)降低到窗口宽度(900)为了保持图像的原始纵横比,我还将降低图像的高度(2000)到1125。为此,我在FITHORIZONTAL中使用了上述逻辑,然后我将使用上述wm_大小代码来设置滚动条位置和拇指长度。不幸的是,即使拇指跟踪器已到达滚动条的末端,也无法显示完整图像。
void CMagDialog::OnVScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar )
{
int nDelta;
int nMaxPos = yMaxScroll;

if(pScrollBar == NULL)  
{
    switch (nSBCode)
    {
    case SB_LINEDOWN:
        if (m_vScrollPos >= nMaxPos)
            return;
        nDelta = min(nMaxPos/100,nMaxPos-m_vScrollPos);
        break;

    case SB_LINEUP:
        if (m_vScrollPos <= 0)
            return;
        nDelta = -min(nMaxPos/100,m_vScrollPos);
        break;

    case SB_PAGEDOWN:
        if (m_vScrollPos >= nMaxPos)
            return;
        nDelta = min(nMaxPos/5,nMaxPos-m_vScrollPos);
        break;

    case SB_THUMBPOSITION:
        nDelta = (int)nPos - m_vScrollPos;
        break;

    case SB_PAGEUP:
        if (m_vScrollPos <= 0)
            return;
        nDelta = -min(nMaxPos/5, m_vScrollPos);
        break;

    default:
        return;
    }
    m_vScrollPos += nDelta;
    SetScrollPos(SB_VERT,m_vScrollPos,TRUE);
    ScrollWindow(0,-nDelta);
}