首页
社区
课程
招聘
[求助]不死心, 再问:"Windows 的“当按 CTRL 键时显示指针是用了什么 API 来实现的?"
发表于: 2009-12-9 05:25 5685

[求助]不死心, 再问:"Windows 的“当按 CTRL 键时显示指针是用了什么 API 来实现的?"

2009-12-9 05:25
5685
【求助】Windows 的“当按 CTRL 键时显示指针是用了什么 API 来实现的?
我想在我的工程中显示一下Windows 的“当按 CTRL 键时显示指针的位置”的效果!!!

前年,大家都叫我用画的, 效果不太好:

procedure TForm1.Button1Click(Sender: TObject);
var
  ScreenDC : HDC;
  PointA : TPoint;
  S_Canvas : TCanvas;
  I, LeltP, BottomP, RightP, TopP : integer;
  RectA : PRect;
begin
  GetCursorPos(PointA);
  ScreenDC:=GetDC(0);
  S_Canvas:=TCanvas.Create;

  with S_Canvas do
  begin
  Pen.Color:=clBlue;
  Pen.Width:=3;
  Handle:=ScreenDC;
  Brush.Style:=bsClear;

    for I := 8 downto 1 do
    begin
    LeltP:=PointA.X - I *  15;
    TopP:=PointA.Y + I * 15;
    RightP:=PointA.X + I * 15;
    BottomP:=PointA.Y - I * 15;
    Ellipse(LeltP,  TopP, RightP, BottomP);
    Sleep(100);
    end;
    InvalidateRect(0, nil, True);
  end;
  DeleteDC(ScreenDC);
end;

[课程]FART 脱壳王!加量不加价!FART作者讲授!

上传的附件:
  • a.jpg (4.52kb,183次下载)
收藏
免费 0
支持
分享
最新回复 (12)
雪    币: 2067
活跃值: (82)
能力值: ( LV9,RANK:180 )
在线值:
发帖
回帖
粉丝
2
什么意思 ?
2009-12-9 06:49
0
雪    币: 125
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
图片和成 DrawIcon 或 TransparentBlt
2009-12-9 09:10
0
雪    币: 14
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
懂了,但不会。。高手支招吧!!哈
2009-12-9 09:20
0
雪    币: 3
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
定位 nt4 source
2009-12-9 19:23
0
雪    币: 297
活跃值: (10)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
6
代码和执行程序都在附件里,看看是不是你要的效果:)
这个是vc9的工程。

vc6可能编译不了。
上传的附件:
2009-12-9 22:21
0
雪    币: 297
活跃值: (10)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
7
实现你这个功能的核心代码在raw_nput_processer.cpp里的:

        if ((WM_KEYUP == uMessage || WM_SYSKEYUP == uMessage) && (VK_CONTROL == curKeyCode))
        {
                HDC hdc = ::GetDC(NULL);
                int nS = ::SaveDC(hdc);
                HPEN hNewPen = ::CreatePen(PS_SOLID, 5, RGB(255, 255, 255));
                HPEN hOldPen = (HPEN)::SelectObject(hdc, hNewPen);
                ::SetROP2(hdc, R2_XORPEN);
                POINT cursorPt;
                ::GetCursorPos(&cursorPt);

                for (int i = 5; i > 0; )
                {
                        int l = i << 5;
                        ::BeginPath(hdc);
                        ::Ellipse(hdc, cursorPt.x - l, cursorPt.y - l, cursorPt.x + l, cursorPt.y + l);
                        ::EndPath(hdc);
                        ::StrokePath(hdc);

                        ::Sleep(100);
       
                        ::BeginPath(hdc);
                        ::Ellipse(hdc, cursorPt.x - l, cursorPt.y - l, cursorPt.x + l, cursorPt.y + l);
                        l = --i << 5;
                        ::EndPath(hdc);
                        ::StrokePath(hdc);
                }

                ::SelectObject(hdc, hOldPen);
                ::DeleteObject(hNewPen);
                ::RestoreDC(hdc, nS);
                ::ReleaseDC(NULL, hdc);
        }
2009-12-9 22:22
0
雪    币: 297
活跃值: (10)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
8
::SetROP2(hdc, R2_XORPEN);
这里用R2_NOT效果会更好!
2009-12-9 23:15
0
雪    币: 189
活跃值: (4810)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
9
谢谢, 效果很完美!!!

但好像不能自定义画笔颜色,如:SetROP2 如果用 R2_COPYPEN , 就不能擦除上次绘制的图形:
不过,好像想要“蓝色”的, 指定“黄色”,就可以得到“蓝色”了。

procedure TForm1.Button1Click(Sender: TObject);
var
  ScreenDC : HDC;
  PointA : TPoint;
  nS, I, LeltP, BottomP, RightP, TopP : integer;
  hNewPen, hOldPen : HPEN;

begin
  ScreenDC:=GetDC(0);
  nS:=SaveDC(ScreenDC);
  hNewPen := CreatePen(PS_SOLID, //指定画笔样式,可以是下述常数之一
                             // PS_SOLID  画笔画出的是实线
                              // PS_DASH  画笔画出的是虚线(nWidth必须是1)
                              // PS_DOT  画笔画出的是点线(nWidth必须是1)
                              // PS_DASHDOT 画笔画出的是点划线(nWidth必须是1)
                              // PS_DASHDOTDOT 画笔画出的是点-点-划线(nWidth必须是1)
                              // PS_NULL 画笔不能画图
                              // PS_INSIDEFRAME 画笔在由椭圆、矩形、圆角矩形、饼图以及弦等生成的封闭对象框中画图。如指定的准确RGB颜色不存在,就进行抖动处理

                      3,  // 以逻辑单位表示的画笔的宽度
                      clYellow); // 画笔的RGB颜色   // clWhite   // clGreen   蓝色

  hOldPen := HPEN(SelectObject(ScreenDC, hNewPen));   // 该函数选择一对象到指定的设备上下文环境中,该新对象替换先前的相同类型的对象。

  SetROP2(ScreenDC,
          R2_XORPEN   //R2_BLACK  //所有绘制出来的像素为黑色
                    // R2_WHITE  //所有绘制出来的像素为白色
                    // R2_NOP // Pixel remains unchanged. //任何绘制将不改变当前的状态
                    // R2_NOT //当前绘制的像素值设为屏幕像素值的反,这样可以覆盖掉上次的绘图,(自动擦除上次绘制的图形)
                    // R2_COPYPEN //使用当前的画笔的颜色
                    // R2_NOTCOPYPEN  //当前画笔的反色

          );  // 该函数的主要的作用是根据nDrawMode设置的方式重新设定绘图的方式
  GetCursorPos(PointA);

    for I := 8 downto 1 do
    begin
    LeltP:=PointA.X - I * 15;
    TopP:=PointA.Y + I * 15;
    RightP:=PointA.X + I * 15;
    BottomP:=PointA.Y - I * 15;

                BeginPath(ScreenDC);
                Ellipse(ScreenDC, LeltP,  TopP, RightP, BottomP);
                EndPath(ScreenDC);
                StrokePath(ScreenDC);

                Sleep(100);

                BeginPath(ScreenDC);
                Ellipse(ScreenDC, LeltP,  TopP, RightP, BottomP);
                EndPath(ScreenDC);
                StrokePath(ScreenDC);
    end;
  SelectObject(ScreenDC, hOldPen);
  DeleteDC(ScreenDC);
  DeleteObject(hNewPen);
  RestoreDC(ScreenDC, nS);
  ReleaseDC(0, ScreenDC);
end;
2009-12-10 03:26
0
雪    币: 189
活跃值: (4810)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
10
编辑出错, 重发了......................
2009-12-10 04:28
0
雪    币: 297
活跃值: (10)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
11
这个是基于gdi的光栅布尔操作来的,这样才能在不需要重绘的情况下擦除先前绘制的颜色。
像ROP_NOT ROP_XOR这些布尔操作恰好可以再一定程度上保存背景信息,从而在第二次绘制的时候将背景恢复,且在视觉上能达到醒目的效果。

如果想指定颜色的话,只能依赖于重绘了这样的整个桌面会闪烁。

至于windows自带那个为什么一直是一种色彩,他可能就不是用的这种方法,应该是在鼠标显示的相关实现里做的。
2009-12-10 08:36
0
雪    币: 189
活跃值: (4810)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
12
谢谢!!!!!!!!!
2009-12-10 13:32
0
雪    币: 189
活跃值: (4810)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
13
谢谢你的帮助,我有一个【求助】通过PID 或 TID得到其主窗口句柄的问题!!! - [悬赏100Kx] ,没人回答,我自已深夜灵机一运,无意找到了好的方法, 但分不能给自已!!!! , 你进来, 我给你分, 好吗?
2009-12-17 04:02
0
游客
登录 | 注册 方可回帖
返回
//