win32窗口映射(部分)
先理解一下“窗口”与“视区”的概念。“窗口”是逻辑坐标下的矩形区域,“视区”是设备坐标系下的区域。根据“窗口”和“视区”的大小可以确定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窗口映射(部分)的更多相关文章
- 第一个手写Win32窗口程序
第一个手写Win32窗口程序 一 Windows编程基础 1 Win32应用程序的基本类型 1.1 控制台程序 不需要完善的Windows窗口,可以使用DOS窗口 的方式显示. 1.2 Win32窗口 ...
- WIN32窗口程序
// Win32.cpp : 定义应用程序的入口点. // #include "stdafx.h" #include "Win32.h" void TRACE( ...
- Win32窗口消息机制 x Android消息机制 x 异步执行
如果你开发过Win32窗口程序,那么当你看到android代码到处都有的mHandler.sendEmptyMessage和 private final Handler mHandler = new ...
- 如何在Console下面生成一个WIN32窗口
一个小挑战? VS2017里面,新建一个控制台工程,输入名字(你不需要也成,有默认的),得到一个控制台工程. 好了,生成的代码,如下: // Win32InConsole.cpp : This fil ...
- Win32窗口框架
Win32窗口框架 WindowClass 单例,负责窗口初始化注册和取消注册: 负责提供静态方法: 放在Window类内部,方便初始化时,wndProc(HandleMsgSetup)的赋值: cl ...
- Win32 - 窗口
Win32 - 窗口 目录 Win32 - 窗口 前言 流程图 创建项目 VS MinGW Win32API字符串 Unicode 和 ANSI 函数 TCHAR WinMain:Win32 Appl ...
- WIN32 窗口封装类实现
CQWnd.h窗口类定义 // QWnd.h: interface for the CQWnd class. // ////////////////////////////////////////// ...
- 解决WIN32窗口不响应WM_LBUTTONDBLCLK消息
原文链接: http://www.cnblogs.com/xukaixiang/archive/2012/05/27/2520059.html 今天在做一个软件时,发现win32创建的窗体不能响应WM ...
- win32窗口程序分析
1.分析消息的附加参数 例如:为了查看程序处理了哪些消息 在回调函数中调用输出函数,在控制台中输出消息的值:
随机推荐
- WINDOWS下调用GetTokenInformation的奇怪之处--两次调用
就是用getLastErr可以得到错误号,同时,会将需要的长度写到参数里,再进行第二次调用,以此来节约内存空间. 神奇的长见识了. 相关说法如下: ====================== The ...
- J - Invitation Cards 最短路
In the age of television, not many people attend theater performances. Antique Comedians of Malidine ...
- 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 ...
- session知识点总结
1.session生成条件是怎样的?是登陆成功才生成?还是请求进来就生成session和sessionid? 答:Tomcat只要进来请求,就会生成session,同一个ip request来源用的都 ...
- javascript 事件对象(event 对象)
原文: http://www.cnblogs.com/songyaqi/p/5204143.html <html> <head> <title> Track Mou ...
- GNS3 使用SecureCRT
"D:\SecureCRT\SecureCRT.EXE" /SCRIPT D:\SecureCRT\DyRouter.vbs /ARG %d /T /TELNET %h %p st ...
- Ubuntu 10.04.3 挂载NTFS移动硬盘
1: fdisk -l #查看所有连接到电脑上的储存设备 2: mkdir -p /mnt/需要掛的分區 #在mnt裏建立準備掛載分區的目錄 3: mount -t ntfs /dev/需要掛的分 ...
- 畅谈HTML开发
现在,打开浏览器,各种各样的页面可以让人眼花缭乱,对于行外人看到的是美观效果是用户体验,对行内人很多其它的是关注技术和创造力. 对于开发者都知道DIV是一对html经常使用标签,DIV+CSS是一对非 ...
- html切换效果
1. 使用方式 <meta HTTP-EQUIV="Page-Enter" CONTENT="revealtrans(duration=1.0, transitio ...
- Swift 进阶
iOS开发系列--Swift进阶 2015-09-21 00:01 by KenshinCui, 3072 阅读, 12 评论, 收藏, 编辑 概述 上一篇文章<iOS开发系列--Swift语言 ...