Solved

Zoom | Scroll

Posted on 1998-05-21
16
617 Views
Last Modified: 2013-11-20
Hi...
Could anyone show me how to zoom ->and<- scroll a bitmap within a CDialog?

First off...
I load a bitmap from file.
I then draw it on the background of the dialog in the OnEraseBkgnd function.


0
Comment
Question by:matzon
  • 8
  • 8
16 Comments
 
LVL 10

Expert Comment

by:RONSLOW
ID: 1313819
How are you displaying the bitmap?  An CBitmapButton? and owner drawn button? a window?

We need to know how you display it before we can tell you how to scroll it.

0
 

Author Comment

by:matzon
ID: 1313820
Edited text of question
0
 

Author Comment

by:matzon
ID: 1313821
Edited text of question
0
 
LVL 10

Accepted Solution

by:
RONSLOW earned 100 total points
ID: 1313822
Do you want it to scroll automtically (like scrolling credits at the end of a movie) or what?

In any case, if you use BitBlt to draw it, change to StretchBlt instead, as this will allow you to zoom and scroll

Perhaps if you post your code for your OnEraseBkgnd I can give you more help

0
 

Author Comment

by:matzon
ID: 1313823
hmmm....
I'll start from the beginning.
Basically, what I am trying to create, is a dialog which can show a bitmap (loaded
from a file). The bitmap should be able to be of any size(256 colors though).

I use a function from Codeguru (LoadBMPImage) to load the image and create the palette.
The following is member variables on my CDialog

      BITMAP bm;
      CBitmap bmp;
      CRect rect;
      CPalette* pPal;

I then override OnEraseBkgnd(CDC* pDC)
and draw the bitmap:

BOOL CElDlg::OnEraseBkgnd(CDC* pDC)
{
      CDC memDC;
      GetClientRect(rect);
      memDC.CreateCompatibleDC(pDC);
      memDC.SelectObject(&bmp);
      bmp.GetBitmap( &bm );
        pDC->BitBlt(0,0,rect.Width(),rect.Height(),
        &memDC,0,0,SRCCOPY);
      return 1;
}

My first problem, is that i need to be able to scroll the dialog in order to see
the entire bitmap.
For this i need to attach 2 scrollbars:

      //Get dialog size
      RECT Coords;
      GetClientRect(&Coords);

      //Set bottom Scroll
      //Get and position scrollbar on bottom ...
      CRect PosBot(0, (Coords.top), (Coords.right-15),        Coords.bottom);
      BotScroll.Create(WS_VISIBLE | SBS_HORZ | SBS_BOTTOMALIGN , PosBot, this, 65000);
      BotScroll.EnableScrollBar();
      BotScroll.SetScrollRange(0,50,true);
      BotScroll.SetScrollPos(0, false);

      //Set Right Scroll
      //Get and position scrollbar at right boder ...
      CRect PosRig(Coords.right, 0, Coords.right, (Coords.bottom-15));
      RigScroll.Create(WS_VISIBLE | SBS_VERT | SBS_RIGHTALIGN , PosRig, this, 65001);
      RigScroll.EnableScrollBar();
      RigScroll.SetScrollRange(0,50,true);
      RigScroll.SetScrollPos(0, false);

But this doesn't work?
The bottom scrollbar blinks???
The scrollbars doesn't increase in position?

At the same time I need to be able to zoom?
I need to create all this within a CDialog, since I can't instanciate a CScrollView from
my main SDi app. Or can I?

I can mail you the program if you wish?
hope this helps you (and in the end me :·))

btw: just out of curiosity are you ->Roger<- Onslow?

0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 1313824
Yes .. I am indeed ->Roger<- Onslow .. do you know of me?

In you draw code you use BitBlt .. change this to a StrtchBlt instead.  Then you can specify the part of the bitmap you want to display and can scale it (by making the source and destination rectangles of different size.

After attaching the scrollbars, you need to respond to the scrolling messages.  These should change the parameters to the StretchBlt so that the approriate part of the bitmap is displayed.  Note that you'll also need to force the dialog to repaint itself or the erase backgroun won't be called again.

Perhaps you'd be better putting the bitmap in an owner-drawn button (say) and have that button along with the scroll bars (and maybe some zoom control) on a dialog.

0
 

Author Comment

by:matzon
ID: 1313825
hmm...
Ill be giving you a B, since the answer is good, but doesn't help a newbie (like me!) that much.
Since the initial question, i have come so far that i am able to zoom and scale a (background drawn)bitmap picture, in a CScrollView.
But this doesn't really help me, since I can't initiate a CScrollView from within my CFormView derived SDI app.
The problem with using a dialog, is that after I create the scrollbars they don't seem to react to a scroll??
I've posted the question on the discussion board at Codeguru, which is were I've heard of you.

Do you disagree with my grading?

-=Shadow=-
0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 1313826
I disagree a little... I never suggested you use a scroll view (did I?) .. And I've told you why your scroll bars aren't working .. and suggested a better (or at least different) was to do what you want.

Surely if the information is not clear enough, then you can just ask me for further info and clarification before grading me.

0
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 

Author Comment

by:matzon
ID: 1313827
No you never suggested the use of CScrollView.
and yes you've told me how to use the scrollbars but they don't work anyway? I override OnVScroll and OnHScroll and set the scrollbars position, but for some strange reason the scrollbars never change position?

About the button solution, I find that to be an strange solution, since that only complicates the process(i.e I now have to scroll and soom a button instead of the initial dialog?)

0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 1313828
You aren't really scrolling the dialog .. but rather the background of it.  A background doesn't scroll when you use scroll bars.

You haven't shown me what your OnVScroll etc code does so that I may be able to help with finding out why it doesn't work.

Having the bitmap in a control in the dialog so that you can add scroll and zoom controls around it seems fairly sensible.  If you prefer the other way, I do have xode that displays a bitmap in a dialog.  It doesn't support scrollbars, but I can see if I can add them for you.  How the user would perform a zoom I don't know .. perhaps clicking on the dislog somewhere?

0
 

Author Comment

by:matzon
ID: 1313829
Well... My code for OnVscroll looks like this:

void OnVScroll( UINT nSBCode, UINT nPos,
CScrollBar* pScrollBar )
{
   //Bottom scrollctrl
   BotScroll.SetScrollPos(nPos, true);
}

If you have the time, I would love to get hands on that code for displaying bitmap in a dialog, preferably with scrollbars..
The zoom capabilities(or ZoomFactor) could be placed on a menu(right click)
But I still need the window to redraw itself?

How would I give you some more points?

Shadow
dm97419@edb.tietgen.dk
0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 1313830
So the handler for when the scroll bar changes simple changes the scroll bar.  Instead, the handler should change the variables that say what part of the image to show.

I'll try changing that sample code I mentioned so that scrollbars will be present (and working, I hope).

Then I can send you the project (or at least the differences).

If this is really helpful for you, you'll either have to post another (dummy) question for me to answer, or get in touch with Linda@experts-exchange.com and/or post a message in the EE Customer Support topics area saying (for example) that you prematurely graded this question with a B and would like to re-grade after receiveing extra help).

All that is, of course, on the condition that I can actually get this working for you ... I wouldn't like you to arrange for a better grade or use up extra points without getting a good result.

0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 1313831
OK .. I started with the MSJ March 1997 C++ article sample code.

This sample displays a window (with menu) and shows a bitmap.  It uses a tooltip to describe the part of the image the mouse is hovering over.  (NOTE: doesn't use a dialog .. but you may find the classes and techniques in this sample useful).

I've changed the sample so that the main window is only half the required height and width, and added the scroll bars.  Now you can scroll around the image using the bars .. and the tooltips still work

I'll post you the sample .. my code is indicated with // RKO comments.

Basically (except for changes to window size and tooltips) I added these to the class definition...

  // RKO added these to keep track of scoll pos and max pos
  int m_nVscrollPos;
  int m_nHscrollPos;
  int m_nVscrollMax;
  int m_nHscrollMax;
  // RKO added this to set scroll bar style
  virtual BOOL PreCreateWindow( CREATESTRUCT& cs );
  // RKO added these to respond to scroll messages
  afx_msg void OnVScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar );
  afx_msg void OnHScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar );

Then made these changes to the class implementation...

// RKO added these handlers to the message map
ON_WM_VSCROLL()
ON_WM_HSCROLL()

in the constructor...

  // RKO initial scroll bar pos (top left)
  m_nVscrollPos = 0;
  m_nHscrollPos = 0;

and added ...

// RKO ensure we have scroll bar style
BOOL CMainFrame::PreCreateWindow( CREATESTRUCT& cs ) {
  BOOL ret = CFrameWnd::PreCreateWindow(cs);
  cs.style |= WS_HSCROLL | WS_VSCROLL;
  return ret;
}

in the OnCreate (for a dialog, OnInitDialog) ...

  // RKO added this to set up scroll bars
  CSize sz = m_dibImage.GetSize(); // size of bitmap
  m_nVscrollMax = sz.cy - mmi.ptMaxSize.y;
  m_nHscrollMax = sz.cx - mmi.ptMaxSize.x;
  SetScrollRange(SB_VERT, 0, m_nVscrollMax, FALSE);
  SetScrollPos(SB_VERT, 0, TRUE);
  SetScrollRange(SB_HORZ, 0, m_nHscrollMax, FALSE);
  SetScrollPos(SB_HORZ, 0, TRUE);

in the OnPaint...

  // RKO setup dest rect based on scroll pos
  CRect rcDst(-m_nHscrollPos,-m_nVscrollPos,-m_nHscrollPos-1,-m_nVscrollPos-1);
  pDIB->Draw(dc,&rcDst);

And finally...

// RKO handle scroll messages

void CMainFrame::OnVScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar ) {
  m_nVscrollPos = GetScrollPos(SB_VERT);
  int nVscrollInc;
  switch (nSBCode) {
  case SB_TOP:
    nVscrollInc = 0 - m_nVscrollPos;
    break;
  case SB_BOTTOM:
    nVscrollInc = m_nVscrollMax - m_nVscrollPos;
    break;
  case SB_LINEUP:
    nVscrollInc = -1;
    break;
  case SB_LINEDOWN:
    nVscrollInc = 1;
    break;
  case SB_PAGEUP:
    nVscrollInc = -8;
    break;
  case SB_PAGEDOWN:
    nVscrollInc = 8;
    break;
  case SB_THUMBTRACK:
    nVscrollInc = nPos - m_nVscrollPos;
    break;
  default:
    nVscrollInc = 0;
  }
  if (nVscrollInc) {
    m_nVscrollPos += nVscrollInc;
    ScrollWindow(0, -nVscrollInc, NULL, NULL);
    SetScrollPos(SB_VERT, m_nVscrollPos, TRUE);
    UpdateWindow();
  }
}

void CMainFrame::OnHScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar ) {
  m_nHscrollPos = GetScrollPos(SB_HORZ);
  int nHscrollInc;
  switch (nSBCode) {
  case SB_LEFT:
    nHscrollInc = 0 - m_nHscrollPos;
    break;
  case SB_RIGHT:
    nHscrollInc = m_nHscrollMax - m_nHscrollPos;
    break;
  case SB_LINEUP:
    nHscrollInc = -1;
    break;
  case SB_LINEDOWN:
    nHscrollInc = 1;
    break;
  case SB_PAGEUP:
    nHscrollInc = -8;
    break;
  case SB_PAGEDOWN:
    nHscrollInc = 8;
    break;
  case SB_THUMBPOSITION:
    nHscrollInc = nPos - m_nHscrollPos;
    break;
  default:
    nHscrollInc = 0;
  }
  if (nHscrollInc) {
    m_nHscrollPos += nHscrollInc;
    ScrollWindow(-nHscrollInc, 0, NULL, NULL);
    SetScrollPos(SB_HORZ, m_nHscrollPos, TRUE);
    UpdateWindow();
  }
}

0
 

Author Comment

by:matzon
ID: 1313832
Hi... Thnx very much...

I've now got a running dialog.
Ofcourse I still need to be able to zoom. But that should be simple (StretchBlt?).

I'll be posting a new question for you!
0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 1313833
The interesting thing is how will the USER tell the program to zoom.  Perhaps a left click to zoom in and right click to zoom out?

0
 

Author Comment

by:matzon
ID: 1313834
hmm I thought of a popop menu to set the zoom factor.


0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
paragon account problem 9 96
Host to IP 7 73
unable to delete all specified values regedit 38 155
wait notify demo infinite loop 3 81
Here is how to use MFC's automatic Radio Button handling in your dialog boxes and forms.  Beginner programmers usually start with a OnClick handler for each radio button and that's just not the right way to go.  MFC has a very cool system for handli…
Introduction: Displaying information on the statusbar.   Continuing from the third article about sudoku.   Open the project in visual studio. Status bar – let’s display the timestamp there.  We need to get the timestamp from the document s…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now