Brad Pirtle
QuickLogic
Article Rev D: 11/8/94
Automatic Scaling in Windows
Many Windows applications need the ability to arbitrarily scale, or zoom, the
contents of a window. An example of this is print preview, where you can zoom in
and out on a portion of the printed page. Programming information on this subject
is minimal and very obfuscated. Not any more! In this article I explain how to easily
use the built it scaling capabilities of Windows, and apply it to a C++ MFC extension
class that I call CZoomView.
Learning To Scale
Proper scaling in Microsoft Windows requires you to set the map mode,
window extent, window origin, viewport extent, and viewport origin for a window.
Are you confused yet? Try reading the manual entries for any corresponding API -
SetWindowExt: Sets the x- and y-extents of the window.... So it wasnt just a
clever name.
A key phrase, however, comes next: defines how GDI maps points in the
logical coordinate system to points in the device coordinate system. Although this
information tells you nothing on how to use it, it is the clue to how it works -- mapping
from one coordinate system to another. To make scaling easy, we want Windows
to do as much of this conversion work as possible. Luckily for us, it can be done
easily if you arm yourself with just a little bit of API knowledge..
For a drawing page to be automatically scaled in a window, two concepts
must be understood. The first is how to draw the page, and the second is how to
view the page. The Windows operating system uses both pieces of information
together so that a user can view your drawing in a window at any arbitrary zooming
scale. As a programmer, the easiest way to understand and implement scaling is to
divide and conquer," handling each concept separately.
Step One: Drawing the Page
The first thing that you need to do is choose the logical units for your
drawing. Think of this as the number of virtual horizontal and vertical units on a page
you will draw on. This is what Windows calls the Window Extent," and is set by the
SetWindowExt API. A logical page size of x by y units would simply have a window
extent of {x, y}. Keep in mind that units is an arbitrary amount of measure that you
pick, so do not be stuck thinking that it has to be pixels, inches, or any other
measure.
Once you choose a logical coordinate system, all GDI drawing will be done
using it. For example, lets say that you want to draw a line from the top left corner to
the bottom right corner of a page that has a window extent of 100 by 100 logical
units. Using the MoveTo and LineTo API functions, you would pass {0, 0} as the
starting logical coordinate to MoveTo, and {100, 100} as the ending logical
coordinate to LineTo. Any other GDI function (Rectangle, Arc, CreateFont, TextOut,
etc.) will also use logical units. // ADD DRAWING ONE HERE
Using logical units allows your program display device independence.
Drawing objects coordinates can all be stored in logical units, and you will use those
coordinates when painting your windows without needing to do any conversions for
scaling, different size screens, or different size windows. Doing any device
dependent conversions, and determining which part of the drawing to actually scale
and display to the user in a window, will be handled automatically by Windows after
you follow the next step.
Step 2: Viewing the Page
Now that you understand logical drawing on your page, the second part of
adding automatic scaling to your program is actually viewing it in a window.
Viewing functionality uses device coordinates, in pixel units.
With this in mind, you need to tell Windows the viewing size, in pixels, of your
entire drawing page. This is what Windows calls the Viewport Extent," and is set by
the SetViewportExt API. This does not confine a real window to that size, but rather
describes the mapping of your logical units into pixels. By setting a window extent
to {100, 100} and a viewport extent of {200, 200}, you are telling Windows that 100
by 100 logical units is exactly equal to 200 by 200 pixels. Note: to help in translating
back and forth from logical to device units, the Windows API supplies the LPtoDP
function to convert logical to device units, and the DPtoLP function to convert back.
When you set window and viewport extents you are required to change the
mapping mode, set by the SetMapMode API. When using the SetWindowExtent
and SetViewportExtent APIs, only two mapping modes are allowed --
MM_ISOTROPIC and MM_ANISOTROPIC. The MM_ISOTROPIC mode is used
when you want identical logical units for both the x and y axes, where
MM_ANISOTROPIC is used for arbitrary logical x and y axis units. For our generic
scaling requirements, we will use the MM_ANISOTROPIC map mode.
The final puzzle piece that Windows needs to do automatic scaling is the
size of the client area of the physical window that will display your drawing (also in
pixels). Because this information is inherent to the window, no API call is
necessary. The pixel size of the window client area is how many pixels of the
viewport will be shown. For example, setting the viewport extent to be the same
number of pixels as the client area of the window would scale the entire logical
drawing to fit the window. Setting the viewport extent to twice the size of the
window's client area would make the user see one forth (half the width and half the
height) of the page, and the drawing will appear larger (or zoomed in). // ADD
DRAWING TWO HERE
The viewport extent is where you control the scaling factor for a window. To
zoom in, increase its size. To zoom out, decrease its size. It really is that easy!
Keep in mind that in order to maintain the original width to height ratio of your logical
drawing, always set the viewport extent to the same ratio as the window extent, and
scale it the same in both the x and y direction.
A Quick Scrolling Primer
Once a window has the ability to scale, zooming in shows only a portion of
the entire drawing. By adding scrolling to the window, the entire drawing can be
viewed without requiring zooming back out. If you are using the MFC C++ class
library, a scrolling class called CScrollView is supplied, which encapsulates all the
necessary Windows scrolling code. For SDK users and those of you that dont
want to read the 700+ lines of code in CScrollView, I will briefly explain the scrolling
concepts needed when using automatic scaling.
To set up scrolling, you need to manipulate the viewport origin using the
SetViewportOrg Windows API. This is the viewports origin in relation to your
windows origin. Because we are scaling by manipulating the viewport only, the
window origin, set with the SetWindowOrg API, should remain {0, 0}.
A good way to visualize origin manipulation for scrolling is to think of your
drawing as a transparency, and the window to display it in as an overhead projector.
The upper left corner of the transparency is the viewport origin, and the upper left
corner of the projector is your windows origin (always {0, 0}). If the transparency is
too big to see all at once (zoomed in), you need to slide it around with your hand
(scroll) to see all of it. To see more to the right, you slide the paper to the left. To
see more down, you slide the paper up.
Applying this back to Windows, to scroll n pixels in a given direction, change
the viewport origin n pixels in the opposite direction. For example, if you started
with both origins at {0, 0} and wanted to scroll 10 pixels to the right and 10 pixels
down, simply set the viewport origin to {-10, -10}.
Putting the Concept to Work in MFC
To demonstrate the above scaling concepts, I have encapsulated it all in an
MFC extension class that I call CZ
没有合适的资源?快使用搜索试试~ 我知道了~
MFC 鼠标选定显示范围,图片放大缩小,带左右滚动条显示
共71个文件
tlog:12个
h:7个
sbr:6个
4星 · 超过85%的资源 需积分: 48 98 下载量 66 浏览量
2018-11-13
17:11:21
上传
评论 7
收藏 29.3MB RAR 举报
温馨提示
MFC中图片缩放,随意使用鼠标画一个方形框,立刻放大显示选择框内的内容,左右2侧滚动条可以随意拖动整体放大后的图像。项目使用vs2013编译。Debug 目录下有demo exe 。
资源推荐
资源详情
资源评论
收起资源包目录
zoom_scale.rar (71个子文件)
zoom_scale
zoom_scale
WDJ_ZOOM.TXT 13KB
ZOOMVIEW
TEST.H 800B
ZOOM32.DSW 535B
TEST.BSC 696KB
Backup
STDAFX.CPP 204B
ZOOM32.MAK 3KB
RESOURCE.H 710B
ZOOM32.PLG 723B
TESTVIEW.CPP 7KB
RES
TEST.ICO 766B
TESTDOC.ICO 766B
TOOLBAR.BMP 598B
TEST.RC2 2KB
ZOOMCURS.CUR 326B
ZOOM32.DSP 4KB
ZOOMVIEW.H 3KB
ZOOM32.sdf 67.69MB
ZOOM32.v12.suo 29KB
TESTVIEW.H 1KB
TESTDOC.CPP 2KB
Debug
vc120.pdb 1.42MB
TESTVIEW.obj 272KB
ZOOM32.ilk 17.44MB
ZOOMVIEW.sbr 0B
TEST.sbr 0B
ZOOM32.log 2KB
MAINFRM.sbr 0B
MAINFRM.obj 254KB
TESTDOC.obj 274KB
ZOOM32.bsc 13.98MB
TEST.obj 265KB
vc120.idb 1.27MB
ZOOMVIEW.obj 292KB
ZOOM32.pdb 25.38MB
STDAFX.obj 231KB
TESTVIEW.sbr 0B
TEST.res 31KB
STDAFX.sbr 0B
ZOOM32.tlog
CL.write.1.tlog 6KB
bscmake.read.1.tlog 1KB
rc.command.1.tlog 628B
link.command.1.tlog 2KB
BscMake.command.1.tlog 1KB
CL.read.1.tlog 219KB
rc.read.1.tlog 8KB
ZOOM32.lastbuildstate 211B
link.write.1.tlog 2KB
cl.command.1.tlog 5KB
rc.write.1.tlog 326B
link.read.1.tlog 7KB
bscmake.write.1.tlog 1KB
TESTDOC.sbr 5.69MB
ZOOM32.exe 7.01MB
ZOOM32.vcxproj 7KB
ZOOM16.EXE 132KB
ZOOM32.OPT 48KB
TEST.CPP 3KB
ZOOM16.DEF 198B
ZOOM16.MAK 3KB
MAINFRM.H 998B
TEST.RC 9KB
TEST.APS 31KB
ZOOM32.sln 957B
ZOOMVIEW.CPP 21KB
ZOOM32.vcxproj.filters 2KB
TESTDOC.H 1KB
TEST.CLW 2KB
STDAFX.H 268B
ZOOM32.positions 40B
UpgradeLog.htm 33KB
MAINFRM.CPP 2KB
共 71 条
- 1
资源评论
- highvision252022-06-12可以用,感谢
- xieyp_dl2019-05-11不错,可用。
- txtfashion2022-08-24不错不错,学习
- turnyou2020-06-17不是我想要的
mruio
- 粉丝: 1
- 资源: 2
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功