﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-ArthasLee-随笔分类-笔记和疑问</title><link>http://www.cppblog.com/ArthasLee/category/16177.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 25 Jul 2011 18:52:46 GMT</lastBuildDate><pubDate>Mon, 25 Jul 2011 18:52:46 GMT</pubDate><ttl>60</ttl><item><title>利用PS快速找屏幕和窗口像素点的坐标</title><link>http://www.cppblog.com/ArthasLee/archive/2011/07/24/151762.html</link><dc:creator>ArthasLee</dc:creator><author>ArthasLee</author><pubDate>Sun, 24 Jul 2011 14:22:00 GMT</pubDate><guid>http://www.cppblog.com/ArthasLee/archive/2011/07/24/151762.html</guid><wfw:comment>http://www.cppblog.com/ArthasLee/comments/151762.html</wfw:comment><comments>http://www.cppblog.com/ArthasLee/archive/2011/07/24/151762.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ArthasLee/comments/commentRss/151762.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ArthasLee/services/trackbacks/151762.html</trackback:ping><description><![CDATA[<div>在写WG或者一些辅助小工具的过程中，难免会涉及到向窗口的某个控件发送鼠标消息，或者是直接点击窗口或者屏幕上的某一个区域。在资料不充分（例如对方使用的是DirectUI，控件的句柄就很难获得，自然也很难知道某个控件或者对象相对于窗口或者屏幕左上角的坐标值）的情况下，很难确定在发送鼠标消息的时候，鼠标的坐标是多少。那么，如何快速地利用工具作简单的查找呢？<br /><br /><br />笔者在制作一个QQ游戏的辅助工具时，就曾经因为一时间找不到两幅图片相对于窗口左上角的坐标而苦恼。<br />（因为这个找茬辅助工具是基于屏幕截图，像素点之间逐一直接比对的）<img border="0" alt="" src="http://www.cppblog.com/images/cppblog_com/arthaslee/2011-07-24-3.jpg" /><br />如何知道上图两个红点分别相对于窗口左上角的坐标值呢？<br />扩展，又如何知道两幅找茬图片的宽度和高度呢？<br /><span style="color: #0000ff">网上不乏好的查找方法，但是为了获取几组值而另外写程序，笔者认为不够灵活。</span><br /><span style="color: #0000ff">程序员还是应该懒一点~</span><br /><br />解决方案如下：<br />运用photoshop的标尺功能即可完成任务：<br />笔者用的是photoshopCS4，估计其他版本也有这个功能。<br /><br />第一步：<br />利用QQ自带的截图功能（TX这回自作聪明了，QQ截图居然可以针对某个特定窗口或者某个特定控件截图，从而省却了全屏截图过后裁切窗口的步骤），截取游戏窗口的PP，如下<img border="0" alt="" src="http://www.cppblog.com/images/cppblog_com/arthaslee/2011-07-24-2.jpg" />：<br /><br />第二步，在photoshopCS4中打开这张图片，放大之，然后在工具栏中选择标尺工具，如图：<br /><img border="0" alt="" src="http://www.cppblog.com/images/cppblog_com/arthaslee/2011-07-24-4.jpg" /><br />标尺工具<br /><br /><br />接着在图片左上角的位置开始，沿着任意方向拖曳标尺工具，就像平时在windows画图中画直线一样，然后我们会看到一条很细的直线被拖出；<br />笔者往下垂直拖曳，这除了能够确定左上角坐标之外，还可以测量出图片的高度。<img border="0" alt="" src="http://www.cppblog.com/images/cppblog_com/arthaslee/2011-07-24-5.jpg" /><br /><span style="color: red"><strong>红色框框</strong></span>里面的灰色线条（两头有十字图案的）就是拖曳出来的直线标尺。<br /><span style="color: #0000ff"><strong>蓝色框框</strong></span>有几组值，熟悉windows窗口编程的童鞋们应该都可以笑而不语了，笔者不才，还是斗胆解说一下：<br /><strong style="color: red">x：相对于图片左上角的像素横坐标</strong>（也就是我们要找的图片或者控件相对于窗口左上角的坐标值）<br /><strong style="color: red">y：相对于图片左上角的像素纵坐标</strong>（同上）<br />w：width，线段两端端点之间的<span style="color: red"><strong>水平宽度</strong></span>（单位是像素）在这里是负数是因为笔者的终点在起点的水平方向左边，因此是负数。<br />h：height，线段两端端点之间的<span style="color: red"><strong>垂直宽度</strong></span>（单位是像素）<br /><br />注意：这里得到的数值是一个小数，其实说白了也是精度问题。<br />平时在做windows窗口编程的<span style="color: #ff0000"><strong>过程中，控件的坐标</strong></span>总是整数，例如上图的x = 9.44，要取9还是取10，那就要看我们在一开始选点的时候是否够贴近真值。<br />这里目测一下（噗！O(&#8745;_&#8745;)O哈哈~），显然是比真实图像稍微偏左了，因此取10，其他值都按照这个方法处理。<br /><br /><br />用这种方法，可以测出两幅图片的左上角坐标和图片的宽、高。获得值之后，运用到程序中，误差不会超过5个像素，到时在测试过程中微调一下就OK了。<br />笔者很幸运，第一次取整的时候就估中了，O(&#8745;_&#8745;)O哈哈~<br /><br />针对QQ游戏大家来找茬，发放一下小屏幕版本的关键数据吧：<br />x1 = 10<br />y1 = 185<br />x2 = 403<br />y2 = 185<br />nWidth = 380<br />nHeight = 285<br /><br /><br />最后恶心一下：祝各位准备YY各种游戏辅助工具的亲们开发愉快，噗哈哈哈哈哈！<br /><br /><strong style="color: #ff0000">谁说只有美工能用PS捏？咱们程序员也可以适当投机取巧一下嘛~哈哈</strong><br /><br /><br /><br /><br /><br /></div><img src ="http://www.cppblog.com/ArthasLee/aggbug/151762.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ArthasLee/" target="_blank">ArthasLee</a> 2011-07-24 22:22 <a href="http://www.cppblog.com/ArthasLee/archive/2011/07/24/151762.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java学习笔记2——JVM和垃圾回收器</title><link>http://www.cppblog.com/ArthasLee/archive/2011/03/04/141128.html</link><dc:creator>ArthasLee</dc:creator><author>ArthasLee</author><pubDate>Fri, 04 Mar 2011 12:49:00 GMT</pubDate><guid>http://www.cppblog.com/ArthasLee/archive/2011/03/04/141128.html</guid><wfw:comment>http://www.cppblog.com/ArthasLee/comments/141128.html</wfw:comment><comments>http://www.cppblog.com/ArthasLee/archive/2011/03/04/141128.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/ArthasLee/comments/commentRss/141128.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ArthasLee/services/trackbacks/141128.html</trackback:ping><description><![CDATA[&nbsp;
<p><span>Q1</span><span>：为什么程序的数据需要放在堆、栈两个不同（甚至更多）的地方？</span></p>
<p>&nbsp;</p>
<p><img border=0 alt="" src="http://www.cppblog.com/images/cppblog_com/arthaslee/1.png" width=728 height=366></p>
<p><span>对于堆和栈中的数据内容来说：</span></p>
<p><span>栈：编译器需知道数据内容的生存周期、但是可以快速管理和分配栈内存；</span></p>
<p><span>堆：编译器无需知道数据内容的生存周期，保证灵活性、但是分配和回收内存不如把数据放在栈中来得快；</span></p>
<p>&nbsp;</p>
<p><span>Q2</span><span>：对象在其生命周期结束后经历什么步骤而后被释放？销毁机制具体是怎样的？底层通过什么实现？</span></p>
<p><span>&nbsp;<img border=0 alt="" src="http://www.cppblog.com/images/cppblog_com/arthaslee/2.png" width=711 height=120></span></p>
<p>&nbsp;</p>
<p><span>当程序执行到一个块</span><span>or</span><span>作用域（</span><span>scope</span><span>）的结尾，会自动清理其维护的栈中的内存数据。</span></p>
<p><span>于是，如果保存在栈中的唯一</span><span>reference</span><span>挂掉了，就意味着再没有办法可以操作其原先引用的对象了。</span></p>
<p><span>但是保存在堆中的对象在这时候还没有被清理掉。</span></p>
<p>&nbsp;</p>
<p>&nbsp;<img border=0 alt="" src="http://www.cppblog.com/images/cppblog_com/arthaslee/3.png" width=756 height=187></p>
<p>&nbsp;</p>
<p><span>对于在堆中，没有被引用的对象。垃圾回收器会直接把他们占据的内存空间释放掉。</span></p>
<p><span>真的如书中所说，这种机制滴水不漏吗？会不会有陷阱？</span></p>
<p><u><span>会不会有一些不经意的操作导致引用计数永远不为零，然而用户却懵然不知呢？</span></u></p>
<p><u><span>内存泄漏真的可以在真正意义上得到避免吗？</span></u></p>
<p>&nbsp;</p>
<p><span>Q3</span><span>：垃圾回收机制究竟能干什么，不能干什么？究竟本质是什么？</span> </p>
<p>&nbsp;</p>
<p>&nbsp;<img border=0 alt="" src="http://www.cppblog.com/images/cppblog_com/arthaslee/4.png" width=715 height=224></p>
<p><span>垃圾回收机制原来只会对</span><span>new</span><span>出来的堆内存起作用！！！</span></p>
<p><span>万一不是</span><span>new</span><span>出来的，那还是得人工回收&#8230;&#8230;</span></p>
<p style="FONT-FAMILY: Comic Sans MS; FONT-SIZE: 18pt">1、You might not get garbage collected！</p>
<p><span>哎&#8230;&#8230;这样的垃圾回收机制啊&#8230;&#8230;</span></p>
<p><img border=0 alt="" src="http://www.cppblog.com/images/cppblog_com/arthaslee/6.png" width=750 height=155></p>
<p><span>还真是懒啊&#8230;&#8230;</span></p>
<p>&nbsp;</p>
<p><span>总之就是，垃圾回收机制只会回收对象在堆中的内存，但究竟这个对象的操作曾经干了什么，有没有&#8220;历史遗留问题&#8221;，</span><span>java</span><span>是一概不管的&#8230;&#8230;</span></p>
<p>&nbsp;<img border=0 alt="" src="http://www.cppblog.com/images/cppblog_com/arthaslee/7.png" width=743 height=60></p>
<p>&nbsp;</p>
<p><span>这个垃圾回收机制还是回到回忆中去吧&#8230;&#8230;（我没吐槽最终幻想，真的没有！）</span></p>
<p>&nbsp;<img border=0 alt="" src="http://www.cppblog.com/images/cppblog_com/arthaslee/8.png" width=750 height=162></p>
<p>&nbsp;</p>
<p><span>ClassName obj</span><span>；</span><span>//</span><span>局部对象，放在栈中（</span><span>C++</span><span>可以这样，</span><span>java</span><span>不行）</span></p>
<p><span>C++</span><span>的好处：作用域结束，局部对象的</span><span>destructor</span><span>自动被调用，释放栈中内存；</span></p>
<p>&nbsp;</p>
<p><span>New</span><span>出来的对象：</span></p>
<p><span>//C++</span><span>的坏处：不执行</span><span>delete</span><span>的话，对象占用的内存会一直赖在堆中。就让内存漏一会儿吧。</span></p>
<p><span>//java</span><span>的好处：不用显式执行，只要作用域结束，</span><span>reference</span><span>被清除，垃圾回收器就会自动回收堆中的内存；</span></p>
<p><span>而且，</span><span>java</span><span>兄还不让你在栈中创建局部对象呢&#8230;&#8230;</span></p>
<p>&nbsp;</p>
<p><span>Q3/1</span><span>：<u>那究竟</u></span><u><span>new</span></u><u><span>操作发生的时候，</span><span>java</span></u><u><span>语言为用户干了什么？</span><span>new</span></u><u><span>的操作也会对引用计数产生作用——例如初始化和创建吗？</span></u><span>垃圾回收器如何工作呢？</span></p>
<p>&nbsp;</p>
<p><img border=0 alt="" src="http://www.cppblog.com/images/cppblog_com/arthaslee/9.png" width=731 height=155></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span>相对于堆而言，在栈中释放和分配内存还是效率较高。这可能也是一些程序的数据放在栈中，一些放在堆中的原因之一吧？</span></p>
<p>&nbsp;</p>
<p><img border=0 alt="" src="http://www.cppblog.com/images/cppblog_com/arthaslee/10.png" width=740 height=282></p>
<p>&nbsp;</p>
<p><span>引用计数类似是一个对象中的成员；有东西引用对象，就增加</span><span>1</span><span>，当有引用在栈中被释放或者设为</span><span>NULL</span><span>，就减少</span><span>1</span><span>；发现引用计数为</span><span>0</span><span>，就证明这个对象已经没人要了&#8230;&#8230;</span></p>
<p><span>缺点：</span></p>
<p><span>垃圾回收器要扫描整个对象列表，查找引用计数为</span><span>0</span><span>的对象；</span></p>
<p><span>如果有两个对象碰巧相互引用了彼此，那这两个对象的引用计数就用不为零，即使没人要也不会被清除掉；</span></p>
<p><span>最悲催的是：</span></p>
<p><span>JVM</span><span>都不是通过这种机制实现垃圾回收滴&#8230;&#8230;</span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span>JVM</span><span>是这么干的&#8230;&#8230;</span></p>
<p><img border=0 alt="" src="http://www.cppblog.com/images/cppblog_com/arthaslee/11.png" width=726 height=214></p>
<p><span>逆向思维，不找死的，找活的！从一个引用出发，遍历其对象</span><span>-</span><span>树（自己作的）。透过每一个在栈中或者在静态区中保存的引用，以之为根节点，遍历由他出发可以到达的对象节点。</span></p>
<p><span>好处：</span></p>
<p><span>不用遍历所有堆中的对象。</span></p>
<p><span>解决两个对象互相引用而导致引用计数恒不为</span><span>0</span><span>的问题；</span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span>经过上述处理，没被找到的对象会被清理掉，但是会留下内存碎片，浪费空间。所以&#8230;&#8230;</span></p>
<p><img border=0 alt="" src="http://www.cppblog.com/images/cppblog_com/arthaslee/12.png" width=742 height=156></p>
<p><span>妙！</span></p>
<p><span>把程序停止下来，把活动的对象</span><span>copy</span><span>到新的堆内存，连续存放，这样就腾出了那些原先成为碎片的空间。</span></p>
<p>&nbsp;</p>
<p><span>然而，一直</span><span>copy</span><span>来</span><span>copy</span><span>去需要有额外的堆内存来保存</span><span>copy</span><span>的数据，实际上</span><span>copy</span><span>发生的时候需要双倍于被</span><span>copy</span><span>内容的堆内存同时可用。</span></p>
<p><span>其次，</span><span>copy</span><span>也需要时空开销&#8230;&#8230;</span></p>
<p><span>于是&#8230;&#8230;</span></p>
<p><span>JVM</span><span>就把</span><span>sweep-and-mark</span><span>和</span><span>stop-and-copy</span><span>结合起来（</span><span>thinking in java</span><span>有详述）</span></p>
<p><span>大对象占用一个</span><span>block</span><span>，每个</span><span>block</span><span>有一个</span><span>generation count</span><span>作为其可用与否的标记。</span></p>
<p><span>一些小对象放在一个</span><span>block</span><span>里；</span></p>
<p><span>根据引用来遍历其对象</span><span>-</span><span>树的操作开始执行：</span></p>
<p><span>一般来说，大对象是不会被</span><span>copy</span><span>的；</span></p>
<p><span>小对象会被复制和重新管理，释放内存碎片；</span></p>
<p><span>JVM</span><span>在碎片多的时候进行</span><span>stop-and-copy</span><span>来整理碎片，腾出空间；在堆内存足够和碎片不多的情况下，则只执行</span><span>sweep-and-mark</span><span>。</span></p>
<p>&nbsp;</p>
<p><span>在这样的垃圾回收机制下，只要是</span><span>new</span><span>出来的东西，真的都能回收了。某程度上还真是滴水不漏啊&#8230;&#8230;</span></p>
<p>&nbsp;</p>
<p><span>显然是抄</span><span>IBM</span><span>大型机的外存管理嘛！数据集放在</span><span>block</span><span>中，被删除的数据集的</span><span>block</span><span>标记为不可用，新建的数据集放在后面的</span><span>block</span><span>中。当存储空间不够了，整理那些已经存在又可用的数据集，存放在一片连续空间中，把碎片重新整理为可用内存，真是&#8230;&#8230;</span></p>
<p><span>抄吧抄吧，不是罪&#8230;&#8230;</span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<img src ="http://www.cppblog.com/ArthasLee/aggbug/141128.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ArthasLee/" target="_blank">ArthasLee</a> 2011-03-04 20:49 <a href="http://www.cppblog.com/ArthasLee/archive/2011/03/04/141128.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>