请问如何重绘一个应用程序的窗体或内部 Object 的边缘,就像 SPY++ 的 FindWindow Tool 实现的样式??

shuixin13 2003-06-07 11:47:47
如上
...全文
31 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
shuixin13 2003-06-12
  • 打赏
  • 举报
回复
:)
对于我的程序来说,这个功能已够用了,
但是还不明白 SPY++ 是怎么做的,
在研究几天!
Intelement 2003-06-12
  • 打赏
  • 举报
回复
上两例中的后一例不是 VC++ 的仿 SPY++ 程序么?
何必做得这么完美
Intelement 2003-06-12
  • 打赏
  • 举报
回复
我的意思是
若某个窗口曾经使用了 SetWindowRgn 函数进行调整
那么 SPY++ 可以完整描绘其边框
对于 Overlay 窗口,SPY++ 好像“无能为力”
shuixin13 2003-06-12
  • 打赏
  • 举报
回复
但是它的 Finder Tool 却是可以的,

它并没有使用 SetWindowRgn API
Intelement 2003-06-12
  • 打赏
  • 举报
回复
当 Windows Media Player 处于隐藏菜单状态的时候(我想其是 Overlay 窗口)
SPY++ 也无法完整的闪烁其完整边框
不过可以用 SPY++ 描绘用 SetWindowRgn 设置某个窗口的边框
shuixin13 2003-06-11
  • 打赏
  • 举报
回复
方法一:
通过 SelectObject 来实现

procedure InvertTracker(hwndDest: HWND);
//画边框
var
hdcDest : HWND;
hPen : HWND;
hOldPen : HWND;
hOldBrush : HWND;
cr : HWND;
rc : TRect;
begin
GetWindowRect(hwndDest, rc);
hdcDest := GetWindowDC(hwndDest);
SetROP2(hdcDest,R2_NOT);
cr := clBlack;
hPen := CreatePen(PS_INSIDEFRAME,2,cr);

hOldPen := SelectObject(hdcDest, hPen);
hOldBrush := SelectObject(hdcDest, GetStockObject(NULL_BRUSH));
Rectangle(hdcDest, 0, 0, rc.Right - rc.Left, rc.Bottom - rc.Top);
SelectObject(hdcDest, hOldBrush);
SelectObject(hdcDest, hOldPen);

ReleaseDC(hwndDest, hdcDest);
DeleteObject(hPen);
end;


方法二:
将边框区域颜色取反

procedure HighlightWindow(hWndWindow: HWND);
var hDCWindow: HDC;
RECT: TRect;
DINV: Integer;
begin
if (hWndWindow = 0) or (Not IsWindow(hWndWindow)) then
Exit
else begin
hDCWindow := GetWindowDC(hWndWindow);
Windows.GetWindowRect(hWndWindow, RECT);
OffsetRect(RECT, -RECT.Left,-RECT.Top);

DINV := 4;
if Not IsRectEmpty(RECT) then
begin
PatBlt(hDCWindow, RECT.Left, RECT.Top, RECT.Right - RECT.Left, DINV, DSTINVERT);
PatBlt(hDCWindow, RECT.left, RECT.bottom - DINV, DINV,
-(RECT.bottom - RECT.top - 2 * DINV), DSTINVERT);
PatBlt(hDCWindow, RECT.right - DINV, RECT.top + DINV, DINV,
RECT.bottom - RECT.top - 2 * DINV, DSTINVERT);
PatBlt(hDCWindow, RECT.right, RECT.bottom - DINV, -(RECT.right - RECT.left),
DINV, DSTINVERT);
end;
ReleaseDC(hWndWindow, hDCWindow);
end;
end;


不过这两个都无法实现异型窗体的高亮,

:(
Intelement 2003-06-09
  • 打赏
  • 举报
回复
画窗口边框线的时候可以采用异或的方式进行,这样就不要刷新窗口了,只要同一个地方画两次就行了。(又是考下来的)
Intelement 2003-06-09
  • 打赏
  • 举报
回复
http://zealsoftstudio.com/articles/qa9810.htm
shuixin13 2003-06-08
  • 打赏
  • 举报
回复
SPY++ 没有使用
DrawEdge
也没有使用任何消息



OffsetRect
GetWindowRect
GetWindowDC
是使用了的
shuixin13 2003-06-08
  • 打赏
  • 举报
回复
:) 效果就是闪烁某个指定窗口的边框,

不过这个边框可不一定是矩形噢!!
GetWindowRect 好像不行吧!!

:)

SPY++ 对不规则窗体照样可以的
Intelement 2003-06-08
  • 打赏
  • 举报
回复
我想楼主的意思是实现像 SPY++ 那样闪烁某个指定的窗口的边框的效果。
1 取得窗口的 Handle
2 取得窗口的边框矩形
3 取得窗口的 HDC
4 在此 HDC 上涂鸦……
5 涂鸦完毕后,SendMessage(窗口, WM_NCPAINT,“你的裤裆被我搞了一个窟窿”, 0)
6 ……

哈哈
实现起来比较烦的吧。
firetoucher 2003-06-08
  • 打赏
  • 举报
回复
不太明白什么意思,你用invalideregn(好像是这个api)可以指定重画的区域
Intelement 2003-06-08
  • 打赏
  • 举报
回复
// 画完之后向这个窗口发送 WM_NCPAINT 消息让他自己重画边框
// 不过代码远远还没有完成呢 ^_^
procedure TForm1.Button1Click(Sender: TObject);
var
hWnd: DWORD;
rc: TRect;
begin
hWnd := Handle;
GetWindowRect(hWnd, rc);
OffsetRect(rc, -Left, -Top);
Windows.DrawEdge(GetWindowDC(hWnd), rc, EDGE_BUMP, BF_RECT);
end;
lion_lh 2003-06-07
  • 打赏
  • 举报
回复
up

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧