GetDC(HWND_DESKTOP)在9997个电话后停止 [英] GetDC(HWND_DESKTOP) stops after 9997 calls

查看:140
本文介绍了GetDC(HWND_DESKTOP)在9997个电话后停止的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的代码在控制台x,y和鼠标指向的像素颜色中写入。 
它正在运行,但有3个故障:

1.在9997次呼叫之后,GetDC(HWND_DESKTOP)停止提供合理的数据。
我的实用解决方案是计算循环,调用指向exe的链接并退出。
2.使用的内存大小增加 - 大约1 kB / loop。
3.它很慢 - 3毫秒是检查单个像素颜色的高价。

请告诉我如何纠正这些问题,特别是1和3.
我的意思是简单易用的MS Express Edition 2013和Windows 7.
我使用类似的代码来通过监控屏幕上几个点的颜色来模拟用户对其他人应用程序的响应。



  #include     stdafx.h 
#include iostream
#include mmdeviceapi.h

使用 命名空间标准;

int _tmain( int argc,_TCHAR * argv [])
{
int x,y,n = 0 ; HDC hdc; POINT curPos; BOOL结果;
执行 {
hdc = GetDC(HWND_DESKTOP);的n ++;
if (n> 9990 ){
ShellExecute(NULL,L < span class =code-string> open,L \C:\\Users \\\\\\Desktop \\xyColor.lnk \
NULL,NULL ,SW_SHOWDEFAULT);
退出( 0 );
}
result = GetCursorPos(& curPos);
if (result){
x = curPos.x;
y = curPos.y;
cout<< n =<< n<< x =<< x<< y =<< y
<< hex<< BGR =<< GetPixel(hdc,x,y)<< dec<< ENDL;
睡眠( 10 );
}
} while (结果);
return 0 ;
}

解决方案

(1)在每次循环迭代中,您都在寻找一个新的DC而且您显然永远不会通过调用返回它ReleaseDC就像你应该的那样。这可能是你的程序在九千次迭代之后耗尽资源的原因。


为什么不在 >循环,而不是内部?



(2)阅读完(1)的评论后,这是非常明白的。



(3)考虑到您正在获取DC并进行一些格式化,此外还要进行10 ms的休眠,因此循环运行慢并不奇怪。


< blockquote>为什么不将桌面位图保存到内存缓冲区并循环检查像素?看起来像获取桌面像素将是一个昂贵的操作,你可以缓冲。



我会看一下屏幕截图的代码示例,然后将屏幕截图保存到一个位图,然后你就可以在内存位图上调用GetPixel。



我给你举个例子但是我在使用DC时非常生疏。


不,单个像素的3毫秒不是高价。如果是大规模像素操作的每像素平均时间,那将是高价。这只是告诉你 GetPixel / SetPixel 只有当你只需要操作一个像素或很少一个像素时才可以接受。对于所有其他情况,此类操作非常慢。你能看出这一点吗?如果你必须触摸3个像素,谁会在乎10毫秒?如果你需要很多像素,你可以加快整体时间,但是可以在一次操作中读取/修改很多像素。



你需要使用 Bitmap :: LockBits http://msdn.microsoft.com/en-us/library/windows/desktop/ms536298%28v=vs.85%29.aspx [ ^ ]。< br $>


-SA


The code below writes in console x,y and color of a pixel pointed by the mouse. 
It's working, but has 3 faults:

1. After 9997 calls GetDC(HWND_DESKTOP) stops giving sensible data.
My pragmatic solution is to count loops, call a link pointing to exe and exit.
2. Size of memory used increases - of order of 1 kB / loop.
3. It is slow - 3 milliseconds is a high price for checking color of a single pixel.

Please tell me how to correct those problems, especially 1 and 3.
I mean something simple and usable with MS Express Edition 2013 and Windows 7.
I use similar code to simulate response of a user to somebody else's application by monitoring color of a few points on the screen.


#include "stdafx.h"
#include "iostream"
#include "mmdeviceapi.h"

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
  int x, y, n = 0;	HDC hdc;	POINT curPos;	BOOL result;
    do {
      hdc = GetDC(HWND_DESKTOP);		n++;
      if (n > 9990) { 
        ShellExecute(NULL, L"open", L"\"C:\\Users\\me\\Desktop\\xyColor.lnk\"", 
	             NULL, NULL, SW_SHOWDEFAULT);
         exit(0);
    } 
    result = GetCursorPos(&curPos);
    if (result) {
      x = curPos.x;
      y = curPos.y;
      cout << "n=" << n << " x=" << x << " y=" << y 
           << hex << " BGR= " << GetPixel(hdc, x, y) << dec << endl;
      Sleep(10);
    }
  } while (result);
  return 0;
}

解决方案

(1) In every loop iteration you are aquiring a new DC and you obviously never return it by calling ReleaseDC as you should. That is probably the reason why your program runs out of resources after nine thousand and something iterations.

Why don't you acquire the hdc before the loop, instead of inside?

(2) Very understandable after you have read my comment for (1).

(3) Considering that you are acquiring a DC and doing some formatting and in addition do a sleep of 10 ms it is not surprising that you loop runs "slow".


Why not save the desktop bitmap to a memory buffer and loop through that to check the pixels? Seems like getting the desktop pixel would be an expensive operation that you can buffer.

I would look at code examples on taking a screen shot, then save the screen shot to a bitmap, then you can call GetPixel on the memory bitmap.

I'd give you an example but I'm pretty rusty in using DC's.


No, 3 milliseconds for individual pixel is not the high price. It would be high price if it was average time per pixel for massive pixel operations. That simply should tell you that GetPixel/SetPixel is only acceptable when you only need to operate on just one pixel or very few of them. For all other cases, such operations are prohibitively slow. Can you see the point? If you have to touch 3 pixels, who would care about 10 milliseconds? If you need many pixels, you can sped more overall time, but its okay as you can read/modify a lot of pixels in one operation.

You need to use Bitmap::LockBits instead: http://msdn.microsoft.com/en-us/library/windows/desktop/ms536298%28v=vs.85%29.aspx[^].

—SA


这篇关于GetDC(HWND_DESKTOP)在9997个电话后停止的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆