概述

调用 SetMapMode 函数可以设置映射模式:

int SetMapMode(
HDC hdc, // 设备环境句柄
int fnMapMode // 要设置的映射模式
);

同样,调用 GetMapMode 函数可以获取映射模式:

int GetMapMode(
HDC hdc // 设备环境句柄
);

注:

  • 默认情况下,映射模式是 MM_TEXT,以像素为单位操作。

  • 映射模式的逻辑坐标只对以设备环境句柄为参数的 GDI 函数有效,非 GDI 函数将继续使用设备坐标

设备坐标系统

  1. 屏幕坐标系统:屏幕左上角坐标为(0,0)

  2. 全窗口坐标系统:窗口边框左上角坐标为(0,0)
  3. 设备坐标系统:客户区左上角坐标为(0,0)

设备坐标和逻辑坐标

设备坐标指视口坐标,逻辑坐标指窗口坐标

在 MM_TEXT 映射模式下,逻辑坐标与设备坐标重合,更改映射模式后,逻辑坐标对设备坐标的映射方法将发生改变。

窗口和视口

调用 SetViewPortOrgEx 函数可以设置视口(设备坐标)的原点

调用 SetWindowOrgEx 函数可以设置窗口(逻辑坐标)的原点

(实际上,这两个函数是改变了设备坐标到逻辑坐标的映射方式,而设备坐标永远是(0,0))

例如 SetViewPortOrgEx ( hdc, 40, 40 ) 其实是将设备坐标(40,40)映射到了逻辑坐标原点(0,0)

例如 SetWindowOrgEx ( hdc, 40, 40 ) 其实是将逻辑坐标(40,40)映射到了设备坐标原点(0,0)

坐标转换

调用 LPToDP 函数可以将逻辑坐标转换成设备坐标

调用 DPToLP 函数可以将设备坐标转换成逻辑坐标

各同向性和各异向性映射模式

当第一次指定各同向性(MM_ISOTROPIC)和各异向性(MM_ANISOTROPIC)的映射模式时, 和 MM_LOMETRIC 映射模式有相同的效果

调用 SetViewPortExtEx 函数可以设置视口(设备坐标)区域的大小(仅在各同向性(MM_ISOTROPIC)和各异向性(MM_ANISOTROPIC)的映射模式中起作用)

调用 SetWindowExtEx 函数可以设置窗口(逻辑坐标)区域的大小(仅在各同向性(MM_ISOTROPIC)和各异向性(MM_ANISOTROPIC)的映射模式中起作用)

(SetWindowExtEx 和 SetViewPortExtEx 函数,必须先后都调用,SetWindowExtEx 最好在 SetViewPortExtEx 前调用,这两个函数的本质是设置一种从逻辑坐标到设备坐标的缩放比例,实际上最终要转换到用以下两个公式来换算逻辑坐标位置映射到的设备坐标位置)

MM_ISOTROPIC 和 MM_ANISOTROPIC 的区别:

MM_ISOTROPIC 会将横纵坐标的缩放比例保持一致(以比例较小的为标准),故当逻辑区域大小改变的时候,图形不会发生拉伸现象,会保持横纵缩放比例一致。

MM_ANISOTROPIC 不会将横纵坐标缩放比例保持一致,故当逻辑区域大小改变的时候,图形将可能会发生拉伸现象。

WHATSIZE 示例程序

#include <windows.h>
#include <strsafe.h> void Show(HWND hwnd, HDC hdc, int xText, int yText, int iMapMode, LPCTSTR szMapMode) {
TCHAR szBuffer[60];
size_t ccLength;
RECT rcClient; SaveDC(hdc);
SetMapMode(hdc, iMapMode);
GetClientRect(hwnd, &rcClient);
DPtoLP(hdc, (LPPOINT)&rcClient, 2);
RestoreDC(hdc, -1); StringCchPrintf(szBuffer, sizeof(szBuffer) / sizeof(TCHAR), TEXT("%-20s %7d %7d %7d %7d"), szMapMode, rcClient.left, rcClient.right, rcClient.top, rcClient.bottom);
StringCchLength(szBuffer, sizeof(szBuffer) / sizeof(TCHAR), &ccLength);
TextOut(hdc, xText, yText, szBuffer, ccLength);
} LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc;
static int cxChar, cyChar;
PAINTSTRUCT ps;
TEXTMETRIC tm;
static TCHAR szHeading[] = TEXT("Mapping Mode Left Right Top Bottom");
static TCHAR szUndLine[] = TEXT("------------ ---- ----- --- ------");
size_t ccLength; switch (message) {
case WM_CREATE:
hdc = GetDC(hwnd);
SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT)); GetTextMetrics(hdc, &tm);
cxChar = tm.tmAveCharWidth;
cyChar = tm.tmHeight + tm.tmExternalLeading; ReleaseDC(hwnd, hdc);
return 0; case WM_PAINT:
hdc = BeginPaint(hwnd, &ps); SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));
SetMapMode(hdc, MM_ANISOTROPIC);
SetWindowExtEx(hdc, 1, 1, NULL);
SetViewportExtEx(hdc, cxChar, cyChar, NULL); StringCchLength(szHeading, sizeof(szHeading) / sizeof(TCHAR), &ccLength);
TextOut(hdc, 1, 1, szHeading, ccLength); StringCchLength(szUndLine, sizeof(szUndLine) / sizeof(TCHAR), &ccLength);
TextOut(hdc, 1, 2, szUndLine, ccLength); Show(hwnd, hdc, 1, 3, MM_TEXT, TEXT("TEXT (pixels)"));
Show(hwnd, hdc, 1, 4, MM_LOMETRIC, TEXT("LOMETRIC (.1 mm)"));
Show(hwnd, hdc, 1, 5, MM_HIMETRIC, TEXT("HIMETRIC (.01 mm)"));
Show(hwnd, hdc, 1, 6, MM_LOENGLISH, TEXT("LOENGLISH (.01 in)"));
Show(hwnd, hdc, 1, 7, MM_HIENGLISH, TEXT("HIENGLISH (.001 in)"));
Show(hwnd, hdc, 1, 8, MM_TWIPS, TEXT("TWIPS (1 / 1440 in)")); EndPaint(hwnd, &ps);
return 0; case WM_DESTROY:
PostQuitMessage(0);
return 0; } return DefWindowProc(hwnd, message, wParam, lParam);
} int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { LPCTSTR lpszClassName = TEXT("WHATSIZE");
LPCTSTR lpszWindowName = TEXT("WHATSIZE Program");
WNDCLASS wndclass;
HWND hwnd;
MSG msg; wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hInstance = hInstance;
wndclass.lpfnWndProc = WndProc;
wndclass.lpszClassName = lpszClassName;
wndclass.lpszMenuName = NULL;
wndclass.style = CS_HREDRAW | CS_VREDRAW; if (!RegisterClass(&wndclass)) {
MessageBox(NULL, TEXT("window class registering failed!"), TEXT("Error"), MB_ICONERROR);
return 0;
} hwnd = CreateWindow(
lpszClassName,
lpszWindowName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL
); ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd); while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
} return msg.wParam;
}

GDI 映射模式(11)的更多相关文章

  1. Windows GDI 映射模式(出自:Windows程序设计第5版-珍藏版)

    GDI映射模式(mapping mode):和映射模式紧密相关的还有4个其它的设备环境属性:1.窗口原点(window origin)2.视口原点(viewport origin)3.窗口范围(win ...

  2. Windows绘图中的GDI映射模式

    对Windows编程新手来说,GDI编程中最困难的部分就是映射模式(Mapping Mode). 什么是映射模式? 我们知道,GDI画图是在设备描述表这个逻辑意义上的显示平面上进行,其使用的是逻辑坐标 ...

  3. GDI绘图中的映射模式CDC::SetMapMode()

    原文链接:http://blog.csdn.net/charlessimonyi/article/details/8264572 在GDI绘图前,一般要设置映射模式.映射模式是什么呢?它是逻辑长度单位 ...

  4. MFC坐标空间与映射模式

    逻辑坐标:使用GDI绘图时使用的坐标系 设备坐标系:实际设备(显示器.打印机)的坐标系,即我们实际看到的坐标系. 坐标空间 在Windows NT/2000中Win32 API中支持以下四层坐标空间: ...

  5. Visual C++ 打印编程技术-编程基础-映射模式

    映射模式: Visual C++ 中采用的坐标映射方式使得用户图形坐标和输出设别的像素完全一致. eg:当屏幕的像素大小为800X600时,每英寸包含屏幕像素为96,打印机则需要几倍的点数才能达到同样 ...

  6. php模式-数据映射模式

    概念:简言之,数据映射模式就是将对象和数据存储映射起来,对一个对象的操作会映射为对数据存储的操作. 深入理解:数据映射,是在持久化数据存储层(一般是关系型数据库)和驻于内存的数据表现层之间进行双向数据 ...

  7. php设计模式 数据对象映射模式

    数据对象映射模式,是将对象和数据存储映射起来,对一个对象的操作会映射为对数据存储的操作. 在代码中实现数据对象映射模式,实现一个ORM类,将复杂的sql语句映射成对象属性的操作.对象关系映射(Obje ...

  8. Hibernate的关联映射——单向1-1关联

    Hibernate的关联映射--单向1-1关联 对于单向的1-1关联关系,需要在持久化类里增加代表关联实体的成员变量,并为该成员变量添加setter方法和getter方法.从持久化类的代码上看,单向1 ...

  9. PHP 设计模式 笔记与总结(10)数据对象映射模式 2

    [例2]数据对象映射模式结合[工厂模式]和[注册模式]的使用. 入口文件 index.php: <?php define('BASEDIR',__DIR__); //定义根目录常量 includ ...

随机推荐

  1. cat<<EOF获取标准输入到文件中

    原文:http://blog.csdn.net/apache0554/article/details/45508631 ---------------------------------------- ...

  2. 多级联动系列——ajax调用XML实现三级联动

    ajax 使用起来特别的方便,再也不操心浏览器兼容问题了.用ajax调用XML页面中的内容,来生成三级联动,OK废话不多说,跟着我一步步写吧. 首先写一个XML文件.data.xml <?xml ...

  3. 使用Django框架实现游戏站点搭建

    完整project链接点击打开链接 上一篇中我们使用了Javascript和Html5实现了弹球游戏.而在本文中我们希望以其为基础实现游戏站点,可以实现用户的注冊登录.游戏成绩记录,排名显示.微博分享 ...

  4. 《编程导论(Java)&#183;3.3.2 按值传递语义》

    不要受<Java编程思想>的影响,计算机科学中的术语--按引用传递(pass-by-reference).不要搞成自说自话的个人用语. 这些术语也不是专门针对Java的,你不应该从某一本J ...

  5. javase - 点餐系统

    public class OrderMsg { public static void main(String[] args) throws Exception { /** * 订餐人姓名.选择菜品.送 ...

  6. C++重载运算符简单总结

    当运算符作用于类类型的运算对象时,可以通过运算符重载重新定义该运算符的含义.明智的使用运算符重载能令我们的程序更易于编写和阅读. 一.基本概念 什么是运算符重载?重载的运算符是具有特殊名字的函数:它们 ...

  7. Mac safari 下iframe的hash取不到BUG

    RT http://192.168.1.66/salaryl#abc 这样的链接是取不到hash的, 需要在最后加上斜杠,如下:http://192.168.1.66/salaryl/#abc fuc ...

  8. Android4.4 wpa_supplicant深入分析之wpa_supplicant初始化流程续

    下面我们将接上一篇文章继续分析main中第二个关键函数wpa_supplicant_add_iface. wpa_supplicant_add_iface用于向wpa_supplicant添加接口设备 ...

  9. 第2章 安装Nodejs 2-4 Linux下安装Nodejs

    linux下编译安装Nodejs  GCC和G++分别是GNU的C和C++编译器.它们在执行编译工作的时候把源代码通过预处理转化成汇编语言生成.i后缀的文件,再由汇编变成目标机器代码,最后连接目标代码 ...

  10. JavaScript表格搜索高亮功能模拟

    在网页表格中模拟excle的搜索高亮显示功能.当在搜索框中输入需要的姓名时,若表格中存在对应的数据,则该表格背景色变为黄色. 下面为表的HTML源码: <!doctype html> &l ...