Delphi 窗口、控件 (实际就是给句柄)闪烁位置,绘制边框
//这种控件就可以 窗口不可以,标题栏是系统绘画的。
procedure TForm1.btn1Click(Sender: TObject); var ahdc,ahdc_old, ahdc_new: HDC; ARect:TRect; ahpen:HPEN; ahandle:THandle; h,w:Integer; pen:integer; i:integer; bmp_old,bmp_new:HBITMAP; begin ahandle := edt1.Handle; ahdc := GetWindowDC(aHandle); if ahdc > 0 then begin GetWindowRect(aHandle, ARect); ahdc_old := CreateCompatibleDC(ahdc); ahdc_new := CreateCompatibleDC(ahdc); bmp_old := CreateCompatibleBitmap(ahdc, ARect.Right-ARect.Left, ARect.Bottom-ARect.Top); bmp_new := CreateCompatibleBitmap(ahdc, ARect.Right-ARect.Left, ARect.Bottom-ARect.Top); SelectObject(ahdc_old, bmp_old); SelectObject(ahdc_new, bmp_new); BitBlt(ahdc_old, 0, 0, ARect.Right-ARect.Left, ARect.Bottom-ARect.Top, ahdc, 0, 0, SRCCOPY); SetBkMode(ahdc, TRANSPARENT); pen := 3; ahpen := CreatePen(PS_SOLID, pen, RGB(255, 0, 0)); SelectObject(ahdc, ahpen); MoveToEx(ahdc, 1, 1, nil); LineTo(ahdc, ARect.Right-ARect.Left, 1); MoveToEx(ahdc, ARect.Right-ARect.Left-pen+1, 1, nil); LineTo(ahdc, ARect.Right-ARect.Left-pen+1, ARect.Bottom-ARect.Top-pen+1); LineTo(ahdc, 1, ARect.Bottom-ARect.Top-pen+1); LineTo(ahdc, 1, 1); BitBlt(ahdc_new, 0, 0, ARect.Right-ARect.Left, ARect.Bottom-ARect.Top, ahdc, 0, 0, SRCCOPY); for i := 1 to 4 do begin Sleep(50); if i mod 2>0 then BitBlt(ahdc,0,0,ARect.Right-ARect.Left, ARect.Bottom-ARect.Top, ahdc_old, 0, 0, SRCCOPY) else BitBlt(ahdc,0,0,ARect.Right-ARect.Left, ARect.Bottom-ARect.Top, ahdc_new, 0, 0, SRCCOPY) end; Sleep(50); BitBlt(ahdc,0,0,ARect.Right-ARect.Left, ARect.Bottom-ARect.Top, ahdc_old, 0, 0, SRCCOPY); DeleteObject(ahpen); ReleaseDC(aHandle,ahdc); DeleteDC(ahdc_old); DeleteObject(bmp_old); DeleteDC(ahdc_new); DeleteObject(bmp_new); end; // EndPaint(Handle,pain); end;
方式2:
uses
Graphics;
// FlashNum 闪烁几次 procedure MyFlashWindow(Wnd: HWND;FlashNum:integer);
//恢复原来的内容 procedure RestoreOrgDC; var SrcDC:HDC; WindowRect: TRect; begin SrcDC := GetWindowDC(Wnd); GetWindowRect(Wnd, WindowRect); OffsetRect(WindowRect,-WindowRect.Left,-WindowRect.Top); BitBlt(SrcDC, WindowRect.Left, WindowRect.Top, WindowRect.Right - WindowRect.Left, WindowRect.Bottom - WindowRect.Top, SrcDC, 0, 0, SRCCOPY); ReleaseDC(Wnd, SrcDC); end; procedure DrawBorder; var DC, MemDC,SrcDC: HDC; MemBitmap, OldBitmap: HBITMAP; WindowRect, HighlightRect: TRect; pen, oldPen: HPEN; oldBrush: HBRUSH; begin // 获取窗口矩形 GetWindowRect(Wnd, WindowRect); HighlightRect := WindowRect; OffsetRect(HighlightRect,-HighlightRect.Left,-HighlightRect.Top); SrcDC := GetWindowDC(Wnd); // 创建兼容的内存DC DC := GetDC(0); MemDC := CreateCompatibleDC(DC); // 创建兼容的内存位图 MemBitmap := CreateCompatibleBitmap(DC, HighlightRect.Right - HighlightRect.Left, HighlightRect.Bottom - HighlightRect.Top); // 选择内存位图到内存DC OldBitmap := SelectObject(MemDC, MemBitmap); //将目标复制到内存DC BitBlt(MemDC, 0, 0, WindowRect.Right-WindowRect.Left, WindowRect.Bottom-WindowRect.Top, SrcDC, 0, 0, SRCCOPY); // SetROP2(MemDC, R2_NOT); //边框 pen := CreatePen(PS_INSIDEFRAME, 3 * GetSystemMetrics(SM_CXBORDER), clBlue); //新的画笔 oldPen := SelectObject(MemDC, pen); //将画刷设置为 NULL_BRUSH 后,绘制矩形只会画出矩形边框。 oldBrush := SelectObject(MemDC, GetStockObject(NULL_BRUSH)); Rectangle(MemDC, HighlightRect.Left-1, HighlightRect.Top-1, HighlightRect.Right+1, HighlightRect.Bottom+1); //使用回原来的笔跟画刷 SelectObject(MemDC, oldBrush); SelectObject(MemDC, oldPen); DeleteObject(pen); OffsetRect(HighlightRect,WindowRect.Left,WindowRect.Top); // 内存DC输出到屏幕 不能直接画到SrcDC上因为 有可能是窗口,标题栏是由系统绘制的,没有效果 BitBlt(DC, HighlightRect.Left, HighlightRect.Top, HighlightRect.Right - HighlightRect.Left, HighlightRect.Bottom - HighlightRect.Top, MemDC, 0, 0, SRCCOPY); // 清理资源 SelectObject(MemDC, OldBitmap); DeleteDC(MemDC); DeleteObject(MemBitmap); ReleaseDC(0, DC); ReleaseDC(Wnd, SrcDC); end; var i:integer; begin for i := 1 to FlashNum do begin if i mod 2 >0 then DrawBorder else RestoreOrgDC; Sleep(100); Application.ProcessMessages; end; if i mod 2 = 0 then RestoreOrgDC; end;