先理解一下“窗口”与“视区”的概念。“窗口”是逻辑坐标下的矩形区域,“视区”是设备坐标系下的区域。根据“窗口”和“视区”的大小可以确定x方向和y方向的比例因子。

 例子如下:

VOID OnPaint(HWND hwnd,WPARAM wParam,LPARAM lParam)
{
PAINTSTRUCT ps;
RECT rtClient;
GetClientRect(hwnd,&rtClient);
HDC hdc = BeginPaint(hwnd, &ps);
HDC hMemDC = CreateCompatibleDC(hdc);
HBITMAP hBitmap = CreateCompatibleBitmap(hdc, rtClient.right - rtClient.left, rtClient.bottom - rtClient.top);//rt为RECT变量;
SelectObject(hMemDC, hBitmap);
FillRect(hMemDC, &rtClient,WHITE_BRUSH); int OldMapMode =SetMapMode(hMemDC,MM_ANISOTROPIC);
//SetViewportOrgEx(hMemDC,0,rtClient.bottom,NULL);
POINT point = {,};
DPtoLP(hMemDC,&point,);
SetWindowOrgEx(hMemDC,-point.x,-point.y,NULL);
RECT rt = {-,-,,};
HBRUSH hBrush = CreateSolidBrush(RGB(,,));
FillRect(hMemDC,&rt,hBrush); //SetViewportOrgEx(hMemDC,0,0,NULL);
SetWindowOrgEx(hMemDC,,,NULL);
SetMapMode(hMemDC,OldMapMode);
BitBlt(hdc, , ,rtClient.right - rtClient.left, rtClient.bottom - rtClient.top,
hMemDC, , , SRCCOPY);
DeleteDC(hMemDC);
DeleteObject(hBitmap);
EndPaint(hwnd,&ps);
}

注:最后最好把设置都改回来(SetViewportOrgEx(hMemDC,0,0,NULL)或者SetWindowOrgEx(hMemDC,0,0,NULL))。

如果设置SetViewportOrgEx则比较简单,直接把逻辑坐标平移就好。

如何设置SetWindowOrgEx则比较麻烦,比如我想平移到100,100这个点,则先要调用DPtoLP进行转换,然后参数是转换后值的取反。(如果不调用DPtoLP函数,则逻辑坐标与设备坐标方向一样,如果不一样,则不需要取反)

比如居中的两种方法,直接写上书中的例子吧(理解就好,MFC版):

设置x轴正方向向右,y轴正方向向上,客户区中心为坐标系为原点。

  (1)、设置视口

pDC->SetWindowExt(rc.Width(),rc.Height());

  pDC->SetViewportExt(rc.Width(),-rc.Height());

pDC->SetViewportOrg(rc.Width()/2,rc.Heigth()/2);

(2)、设置窗口

  pDC->SetWindowExt(rc.Width(),-rc.Height());

  pDC->SetViewportExt(rc.Width(),rc.Height());

pDC->SetWindowOrg(-rc.Width()/2,rc.Heigth()/2);

分析第二种:由于设备与逻辑坐标比率是1比1,所以不需要转换坐标,准备偏移点为(rc.Width()/2,rc.Heigth()/2),由于逻辑与设备坐标系x方向相同,y方向不同,所以x取反,y不需要取反,结果为(-rc.Width()/2,rc.Heigth()/2);

  第二种亦可以换成类似:(win32资料,这是我自己的测试代码)

    SetWindowExtEx(hMemDC,rtClient.right,-2*rtClient.bottom,NULL);
    SetViewportExtEx(hMemDC,rtClient.right,rtClient.bottom,NULL);
    POINT point = {rtClient.right/2,rtClient.bottom/2};
    DPtoLP(hMemDC,&point,1);
    SetWindowOrgEx(hMemDC,-point.x,-point.y,NULL);

通过设置原点变成极坐标,然后可以方便计算。比如计算机图形学基础教程有一道题。

把一个半径为R的圆40等份,以每个等分点为圆心,以r为半径画圆。

  

  RECT rtClient;
GetClientRect(hwnd,&rtClient);
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd,&ps);
SetMapMode(hdc,MM_ANISOTROPIC);
SetViewportExtEx(hdc,rtClient.right,rtClient.bottom,NULL);
SetWindowExtEx(hdc,rtClient.right,-rtClient.bottom,NULL);
POINT pt = {rtClient.right/,rtClient.bottom/};
DPtoLP(hdc,&pt,);
SetWindowOrgEx(hdc,-pt.x,-pt.y,NULL);
HBRUSH hBrush = (HBRUSH)GetStockObject(NULL_BRUSH);
HBRUSH hOldBrush = (HBRUSH)SelectObject(hdc,hBrush);
int bigR = ;
int smallR = ;
for(int i=;i<;++i)
{
int x = (int)(cos(0.0+*i)*bigR);
int y = (int)(sin(0.0+*i)*bigR);
Ellipse(hdc,x-smallR,y-smallR,x+smallR,y+smallR);
}
SetWindowOrgEx(hdc,,,NULL);
SelectObject(hdc,hOldBrush); EndPaint(hwnd,&ps);

效果图:

  

注:参考资料:http://www.cppblog.com/dragon/archive/2012/09/07/64005.html

win32窗口映射(部分)的更多相关文章

  1. 第一个手写Win32窗口程序

    第一个手写Win32窗口程序 一 Windows编程基础 1 Win32应用程序的基本类型 1.1 控制台程序 不需要完善的Windows窗口,可以使用DOS窗口 的方式显示. 1.2 Win32窗口 ...

  2. WIN32窗口程序

    // Win32.cpp : 定义应用程序的入口点. // #include "stdafx.h" #include "Win32.h" void TRACE( ...

  3. Win32窗口消息机制 x Android消息机制 x 异步执行

    如果你开发过Win32窗口程序,那么当你看到android代码到处都有的mHandler.sendEmptyMessage和 private final Handler mHandler = new ...

  4. 如何在Console下面生成一个WIN32窗口

    一个小挑战? VS2017里面,新建一个控制台工程,输入名字(你不需要也成,有默认的),得到一个控制台工程. 好了,生成的代码,如下: // Win32InConsole.cpp : This fil ...

  5. Win32窗口框架

    Win32窗口框架 WindowClass 单例,负责窗口初始化注册和取消注册: 负责提供静态方法: 放在Window类内部,方便初始化时,wndProc(HandleMsgSetup)的赋值: cl ...

  6. Win32 - 窗口

    Win32 - 窗口 目录 Win32 - 窗口 前言 流程图 创建项目 VS MinGW Win32API字符串 Unicode 和 ANSI 函数 TCHAR WinMain:Win32 Appl ...

  7. WIN32 窗口封装类实现

    CQWnd.h窗口类定义 // QWnd.h: interface for the CQWnd class. // ////////////////////////////////////////// ...

  8. 解决WIN32窗口不响应WM_LBUTTONDBLCLK消息

    原文链接: http://www.cnblogs.com/xukaixiang/archive/2012/05/27/2520059.html 今天在做一个软件时,发现win32创建的窗体不能响应WM ...

  9. win32窗口程序分析

    1.分析消息的附加参数 例如:为了查看程序处理了哪些消息   在回调函数中调用输出函数,在控制台中输出消息的值:

随机推荐

  1. noip模拟赛 水题

    题目描述 LYK出了道水题. 这个水题是这样的:有两副牌,每副牌都有n张. 对于第一副牌的每张牌长和宽分别是xi和yi.对于第二副牌的每张牌长和宽分别是aj和bj.第一副牌的第i张牌能覆盖第二副牌的第 ...

  2. hdu 1527威佐夫博弈

    //http://www.cnblogs.com/bo-tao/archive/2012/04/16/2452633.html #include<stdio.h> #include< ...

  3. AbstractList 重写 equals() 方法

    题目内容 题目内容很简单,就是创建 ArrayList 和 Vector 集合,向两者添加相同内容的字符串,最后用 equals() 方法比较是否相等. 这里就考察了 "==" 和 ...

  4. MyBatis3-缓存使用

    一级缓存和二级缓存的区别: 1.一级缓存:基于PerpetualCache的HashMap本地缓存,其存储作用域为同一个SqlSession,当Session flush或close之后,该Sessi ...

  5. Python3基础(十二) 学习总结·附PDF

    Python是一门强大的解释型.面向对象的高级程序设计语言,它优雅.简单.可移植.易扩展,可用于桌面应用.系统编程.数据库编程.网络编程.web开发.图像处理.人工智能.数学应用.文本处理等等. 在学 ...

  6. 1064. Complete Binary Search Tree (30)【二叉树】——PAT (Advanced Level) Practise

    题目信息 1064. Complete Binary Search Tree (30) 时间限制100 ms 内存限制65536 kB 代码长度限制16000 B A Binary Search Tr ...

  7. Java原型模式之浅拷贝-深拷贝

    一.是什么? 浅拷贝:对值类型的成员变量进行值的复制,对引用类型的成员变量仅仅复制引用,不复制引用的对象 深拷贝:对值类型的成员变量进行值的复制,对引用类型的成员变量也进行引用对象的复制 内部机制: ...

  8. 速度上手LM4F LaunchPad 输出多路PWM波

    最近转战到TI的Cortex M4平台后,发现网上关于TI的LM4F120 Launchpad 资料太少了,而且其中大部分都是TI员工或者其合作伙伴提供的,例程太少,导致新手上手很慢. 我只是要实现几 ...

  9. HDU 5858Hard problem

    Hard problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tota ...

  10. 【POJ 3974】 Palindrome

    [题目链接] http://poj.org/problem?id=3974 [算法] 解法1 : 字符串哈希 我们可以分别考虑奇回文子串和偶回文子串,从前往后扫描字符串,然后二分答案,检验可以用哈希 ...