先理解一下“窗口”与“视区”的概念。“窗口”是逻辑坐标下的矩形区域,“视区”是设备坐标系下的区域。根据“窗口”和“视区”的大小可以确定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. WINDOWS下调用GetTokenInformation的奇怪之处--两次调用

    就是用getLastErr可以得到错误号,同时,会将需要的长度写到参数里,再进行第二次调用,以此来节约内存空间. 神奇的长见识了. 相关说法如下: ====================== The ...

  2. J - Invitation Cards 最短路

    In the age of television, not many people attend theater performances. Antique Comedians of Malidine ...

  3. v$log and v$logfiles

    v$log has one row for each group. v$logfile has one row for each file. There is a status column for ...

  4. session知识点总结

    1.session生成条件是怎样的?是登陆成功才生成?还是请求进来就生成session和sessionid? 答:Tomcat只要进来请求,就会生成session,同一个ip request来源用的都 ...

  5. javascript 事件对象(event 对象)

    原文: http://www.cnblogs.com/songyaqi/p/5204143.html <html> <head> <title> Track Mou ...

  6. GNS3 使用SecureCRT

    "D:\SecureCRT\SecureCRT.EXE" /SCRIPT D:\SecureCRT\DyRouter.vbs /ARG %d /T /TELNET %h %p st ...

  7. Ubuntu 10.04.3 挂载NTFS移动硬盘

    1: fdisk -l #查看所有连接到电脑上的储存设备 2:  mkdir -p /mnt/需要掛的分區 #在mnt裏建立準備掛載分區的目錄 3:  mount -t ntfs /dev/需要掛的分 ...

  8. 畅谈HTML开发

    现在,打开浏览器,各种各样的页面可以让人眼花缭乱,对于行外人看到的是美观效果是用户体验,对行内人很多其它的是关注技术和创造力. 对于开发者都知道DIV是一对html经常使用标签,DIV+CSS是一对非 ...

  9. html切换效果

    1. 使用方式 <meta HTTP-EQUIV="Page-Enter" CONTENT="revealtrans(duration=1.0, transitio ...

  10. Swift 进阶

    iOS开发系列--Swift进阶 2015-09-21 00:01 by KenshinCui, 3072 阅读, 12 评论, 收藏, 编辑 概述 上一篇文章<iOS开发系列--Swift语言 ...