Solved

CScrollView Limitation on Windows 95

Posted on 1998-09-08
5
564 Views
Last Modified: 2013-11-20
I use WindowsNT on my PC but when i was using my programs on windows 95 I discovered that his GDI subsystem is still 16-bit, but the CScrollView class uses 32-bit integers into

CDC::SetWindowExt CDC::SetViewportExt

if document's dimensions exceedes the limits of a 16-bit signed integer (-32768 to +32767), that truncation causes the GDI subsystem to receive incorrect information.

Is it possible to bypas this proble ?

Is this problem fixed in windows 98 ?

excuse my english but I'm writing from Italy !

0
Comment
Question by:quetzalcoatl
5 Comments
 
LVL 1

Expert Comment

by:Bridge
ID: 1321897
the size of an int is system dependent. You can find the length using;
int nNumberOfBytes = sizeof(int);
0
 
LVL 2

Expert Comment

by:jstolan
ID: 1321898
Yes, it is possible to bypass this problem.  A method is shown below.  I'm sorry, but I don't know if this problem is fixed in Windows 98 or not.

Now as to working around the problem.  I'm presuming you're deriving your view class from CScrollView.  You need to override the OnScroll function, and replace it with something like this:

In the function below, m_iLastThumb is a member variable of your derived class, which is initialized to 0 in your constructor.  Note that I also use my own variables for m_szLineScroll and m_szPageScroll rather than the CScrollView variables.  This is for a customization feature that I need, but you probably don't require.  You should probably use the MFC default values for these m_pageDev and m_lineDev respectively:

Good Luck

---------------------------------------------------------------


BOOL CMyView::OnScroll(UINT nScrollCode,UINT nPos,BOOL bDoScroll)
{
    // This function was copied from CScrollView, but modified to fix SB_THUMBTRACK
    // on the vertical scroll bar handler.

    // calc new x position
    int x = m_hScroll.GetScrollPos();
    int xOrig = x;
   
    switch (LOBYTE(nScrollCode))
    {
    case SB_TOP:
        x = 0;
        break;
    case SB_BOTTOM:
        x = INT_MAX;
        break;
    case SB_LINEUP:
        x -= m_szLineScroll.cx;
        break;
    case SB_LINEDOWN:
        x += m_szLineScroll.cx;
        break;
    case SB_PAGEUP:
        x -= m_szPageScroll.cx;
        break;
    case SB_PAGEDOWN:
        x += m_szPageScroll.cx;
        break;
    case SB_THUMBTRACK:
        x = nPos;
        break;
    }
   
    // calc new y position
    int y = m_vScroll.GetScrollPos();
    int yOrig = y;
   
    switch (HIBYTE(nScrollCode))
    {
    case SB_TOP:
        y = 0;
        m_iLastThumb = y;
        break;
    case SB_BOTTOM:
        y = INT_MAX;
        m_iLastThumb = y;
        break;
    case SB_LINEUP:
        y -= m_szLineScroll.cy;
        m_iLastThumb = y;
        break;
    case SB_LINEDOWN:
        y += m_szLineScroll.cy;
        m_iLastThumb = y;
        break;
    case SB_PAGEUP:
        y -= m_szPageScroll.cy;
        m_iLastThumb = y;
        break;
    case SB_PAGEDOWN:
        y += m_szPageScroll.cy;
        m_iLastThumb = y;
        break;
    case SB_THUMBTRACK:
        // This is an unreal Kluge but it appears to be necessary
        y = nPos;
        // nPos value has FFFF in msb if bit 15 is set, 0000 if bit 15 is clear
        // It is not (as one would expect) a 32 bit value! so we strip off MSW
        if( y < 0 ) y &= 0x0000FFFF;
        // We retrieve the last thumb position (which we own), and make it 16 bit like nPos
        int iYTest = m_iLastThumb & 0x0000FFFF;
        // If we scrolled past 16 bit boundary forward, increment last scroll position MSW
        if( ( iYTest > 0xC000 ) && ( y < 0x04000 ) )
            m_iLastThumb += 0x00010000;
        // If we scrolled past 16 bit boundary backward, decrement last scroll position MSW
        if( ( iYTest < 0x4000 ) && ( y > 0x0C000 ) )
            m_iLastThumb -= 0x00010000;
        // Now m_iLastThumb MSW is correct and y has correct LSW
        m_iLastThumb &= 0xFFFF0000;
        // Combine them
        y = y + m_iLastThumb;
        // and remember it for next time
        m_iLastThumb = y;
        break;
    }
   
    BOOL bResult = OnScrollBy(CSize(x - xOrig, y - yOrig), bDoScroll);
    if (bResult && bDoScroll)
    {
        CRect rcClient;
        GetClientRect( &rcClient);
        rcClient.top+=m_iHeight;
        if( m_hScroll.IsWindowVisible() ) rcClient.bottom -=GetSystemMetrics( SM_CYHSCROLL );
        if( m_vScroll.IsWindowVisible() ) rcClient.right -=GetSystemMetrics( SM_CXVSCROLL );
        InvalidateRect(&rcClient);
        UpdateWindow();
    }
   
    return bResult;
}



0
 

Author Comment

by:quetzalcoatl
ID: 1321899
This solution doesn't work because the GDI subsistem of Windows95 make something crazy when yo draw a line out of
(-32768 to +32767), so the problem is not just in scrolling control but also in drawing objects (line,polyline,etc) in a real world coordinate, not just in this range.

thanks anyway !

:)

0
 
LVL 2

Accepted Solution

by:
milenvk earned 190 total points
ID: 1321900
There is no way to draw more outside of the 16 bit GDI range in Win 95. But there is an answer to your problem and it is called
"Mapping". You can map logical coordinates that you use to draw to phisical coordinates that the device uses to display the data. Suppose you want to draw a really long line that exeeds in pixels the 16 bit int range twice. You can set such a mapping mode to your device context that given a line for example from x1 = -32768 to x2 = 32768 and y1 = y2 = 0 will be actually 131074 pixels long, i.e. the mapping is 1:2. Here's how you can do that:

void OnDraw(CDC *pDC)
{
  pDC->SetMapMode(MM_ANISOTROPIC);
  pDC->SetWindowExt(1, 1);
  pDC->SetViewportExt(2, 2);
  pDC->MoveTo(-32768, 0);
  pDC->LineTo(32768, 0);
}

In this way using SetWindowExt and SetViewportExt you can set literally any mapping you need. The mapping will apply for all the DC functions that work with logical coordinates. In this way you build a logical coordinate of your own and it is mapped by the system to the real coordinate system using the mapping that you specify. However you still have to use 16 bit integers in your own logical coordinate system, which means that there should be some calculations, but that's not a big problem - you can always divide by 2 in the above example right before calling the MoveTo and LineTo functions, i.e. you can still emulate a bigger range coordinate system. And that's thanks to the mapping of the DC. There's another pitfall however: the functions that receive phhisical (i.e. device) coordinates, (like OnScroll()) will still work with the 16 bit phisical coordinate system, so you still have to use the jstolans solution or a simlar one...
Good luck :-)
0
 
LVL 7

Expert Comment

by:psdavis
ID: 1321901
> if document's dimensions exceedes the limits of a 16-bit signed integer (-32768 to +32767), that truncation causes the GDI subsystem to receive incorrect information.

You're best way is to use the SetWindowExt and SetViewportExt to scale all of your drawing features to be under your limit.  

The Extents definitely don't do anything magical.  All it does is creates a 'zoom' factor for converting during drawing.  Therefore, if you're drawing extents are outside of the standard 'short int' range, then divide your SetWindowExt by the appropriate amount.

For example, since your 'zoom' ratio is ViewportExt.cx / WindowExt.cx, then multiply your WindowExt.cx by 10, and then divide all of your drawing points by 10.  Then you 'might' be ok.

p.s. Win98 doesn't fix the problem.  You might consider NT instead.

Phillip



0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

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…
Have you tried to learn about Unicode, UTF-8, and multibyte text encoding and all the articles are just too "academic" or too technical? This article aims to make the whole topic easy for just about anyone to understand.
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 explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

744 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

11 Experts available now in Live!

Get 1:1 Help Now