inline void ink( PIX* pix, int step, int a ) { int ia = ALPHA_MAX - a; AlphaBlend( *(pix-step), m_r, m_g, m_b, a, ia ); *(pix) = m_c; AlphaBlend( *(pix+step), m_r, m_g, m_b, ia, a ); }
void image::alphaRender(HDC hdc, int destX, int destY, int sourX, int sourY, int sourWidth, int sourHeight, bool reverse, BYTE alpha, BOOL bAlphaFormat) { _blendFunc.SourceConstantAlpha = alpha; if (bAlphaFormat) _blendFunc.AlphaFormat = AC_SRC_ALPHA; HDC hTempDC; if (reverse) { hTempDC = _imageInfo->hMemDC2; } else { hTempDC = _imageInfo->hMemDC; } if (_trans) { //출력해야될DC에 그려져있는 내용을 Blend에 그린다. BitBlt(_blendImage->hMemDC, 0, 0, _imageInfo->width, _imageInfo->height, hdc, destX, destY, SRCCOPY); //출력해야될 이미지를 Blend에 그린다. GdiTransparentBlt(_blendImage->hMemDC, 0, 0, sourWidth, sourHeight, hTempDC, sourX, sourY, sourWidth, sourHeight, _transColor); //BlendDC를 출력해야 될 DC에 그린다. AlphaBlend(hdc, destX, destY, sourWidth, sourHeight, _blendImage->hMemDC, 0, 0, sourWidth, sourHeight, _blendFunc); } else { AlphaBlend(hdc, destX, destY, sourWidth, sourHeight, hTempDC, sourX, sourY, sourWidth, sourHeight, _blendFunc); } }
void image::alphaRender(HDC hdc, int destX, int destY, int sourX, int sourY, int sourWidth, int sourHeight, BYTE alpha) { if (!_blendImage) alphaInit(); _blendFunc.SourceConstantAlpha = alpha; if (_trans) { //출력해야 될 DC에 그려져 있는 내용을 blend에 그려준다 BitBlt(_blendImage->hMemDC, 0, 0, _imageInfo->width, _imageInfo->height, hdc, destX, destY, SRCCOPY); //출력해야 될 이미지를 blend에 그려준다 GdiTransparentBlt(_blendImage->hMemDC, 0, 0, sourWidth, sourHeight, _imageInfo->hMemDC, sourX, sourY, sourWidth, sourHeight, _transColor); //blendDC를 출력해야 될 DC에 그린다 AlphaBlend(hdc, destX, destY, sourWidth, sourHeight, _blendImage->hMemDC, 0, 0, sourWidth, sourHeight, _blendFunc); } else { AlphaBlend(hdc, destX, destY, sourWidth, sourHeight, _imageInfo->hMemDC, sourX, sourY, sourWidth, sourHeight, _blendFunc); } }
inline void ink( PIX* pix, int step, int a ) { int ia = ALPHA_MAX - a; int o=-W/2+1; AlphaBlend( *(pix+o*step), m_r, m_g, m_b, a, ia ); for ( ; o<=W/2; o++ ) { *(pix+o*step) = m_c; } AlphaBlend( *(pix+o*step), m_r, m_g, m_b, ia, a ); }
void ac::MirrorAll(cv::Mat &frame) { cv::Mat copies[4]; for(int i = 0; i < 4; ++i) copies[i] = frame.clone(); MirrorLeft(copies[0]); MirrorRight(copies[1]); MirrorTopToBottom(copies[2]); MirrorBottomToTop(copies[3]); cv::Mat out[2]; AlphaBlend(copies[0], copies[1], out[0], 0.5); AlphaBlend(copies[2], copies[3], out[1], 0.5); AlphaBlend(out[0], out[1], frame, 0.5); AddInvert(frame); }
void ac::ShuffleAlphaWithRGB(cv::Mat &frame) { cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); ShuffleAlpha(copy1); ShuffleRGB(copy2); AlphaBlend(copy1, copy2, frame, 0.5); AddInvert(frame); }
void ac::ImageReverseSubFilter(cv::Mat &frame) { if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "ImageReverseSubFilter") return; cv::Mat reimage; cv::resize(blend_image, reimage, frame.size()); cv::Mat all_frames[3]; cv::flip(frame, all_frames[0], -1); cv::flip(frame, all_frames[1], 0); cv::flip(frame, all_frames[2], 1); cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); for(int z = 0; z < copy1.rows; ++z) { for(int i = 0; i < copy1.cols; ++i){ cv::Vec3b &pixel = copy1.at<cv::Vec3b>(z, i); cv::Vec3b pix[4]; for(int j = 0; j < 3; ++j) { pix[j] = all_frames[j].at<cv::Vec3b>(z, i); } for(int j = 0; j < 3; ++j) { pixel[j] = pix[0][j] ^ pix[1][j] ^ pix[2][j] ^ pixel[j]; } } } static MatrixCollection<8> collection; Smooth(copy1, &collection); CallFilter(subfilter, reimage); Xor(reimage, copy1); AlphaBlend(reimage, copy2, frame, 0.5); DarkenFilter(frame); MedianBlend(frame); }
// based on http://theartofdev.wordpress.com/2013/10/24/transparent-text-rendering-with-gdi/, // TODO: look into using http://theartofdev.wordpress.com/2014/01/12/gdi-text-rendering-to-image/ // TODO: doesn't actually look good (i.e. similar to DrawText when using transparent SetBkMode()) // which kind of makes sense, because I'm using transparent mode to draw to in-memory bitmap as well // TODO: doesn't actually do alpha bf.SourceConstantAlpha > 4 looks the same, values 1-4 produce // different, but not expected, results // TODO: I would like to figure out a way to draw text without the need to Lock()/Unlock() // maybe draw to in-memory bitmap, convert to Graphics bitmap and blit that bitmap to // Graphics object void TextRenderGdi::DrawTransparent(const WCHAR *s, size_t sLen, RectF& bb, bool isRtl) { CrashIf(!hdcGfxLocked); // hasn't been Lock()ed int x = (int) bb.X; int y = (int) bb.Y; int dx = (int) bb.Width; int dy = (int) bb.Height; CreateClearBmpOfSize(dx,dy); //SetBkMode(hdcGfxLocked, 1); SetBkMode(memHdc, TRANSPARENT); //BitBlt(memHdc, 0, 0, dx, dy, hdcGfxLocked, x, y, SRCCOPY); SelectObject(memHdc, currFont); ::SetTextColor(memHdc, textColor.ToCOLORREF()); #if 0 TextOut(memHdc, 0, 0, s, sLen); #else UINT opts = 0; //ETO_OPAQUE; if (isRtl) opts = opts | ETO_RTLREADING; ExtTextOut(memHdc, 0, 0, opts, nullptr, s, (UINT)sLen, nullptr); #endif BLENDFUNCTION bf = {}; bf.BlendOp = AC_SRC_OVER; bf.BlendFlags = 0; bf.AlphaFormat = 0; // 0 - ignore source alpha, AC_SRC_ALPHA (1) - use source alpha bf.SourceConstantAlpha = 0x3; //textColor.GetA(); AlphaBlend(hdcGfxLocked, x, y, dx, dy, memHdc, 0, 0, dx, dy, bf); }
BOOL CSonicImage::InternalDraw(HDC hdc, int x, int y, DRAW_PARAM * pDp) { CRect rtSrc, rtDest; rtDest = CalculateRectByDrawParam(x, y, pDp, rtSrc); if(IsAlphaChannelValid() || (pDp && (pDp->dwMask & DP_ALPHA))) { BLENDFUNCTION blend; blend.AlphaFormat = AC_SRC_ALPHA; blend.BlendFlags = 0; blend.BlendOp = AC_SRC_OVER; blend.SourceConstantAlpha = (pDp && (pDp->dwMask & DP_ALPHA)) ? pDp->cAlpha : 255; AlphaBlend(hdc, rtDest.left, rtDest.top, rtDest.Width(), rtDest.Height(), m_Dib.GetSafeHdc(), rtSrc.left, rtSrc.top, rtSrc.Width(), rtSrc.Height(), blend); } else { if(pDp && (pDp->dwMask & DP_COLOR_KEY)) { TransparentBlt(hdc, rtDest.left, rtDest.top, rtDest.Width(), rtDest.Height(), m_Dib.GetSafeHdc(), rtSrc.left, rtSrc.top, rtSrc.Width(), rtSrc.Height(), pDp->dwColorKey); } else if(pDp && (pDp->dwMask & DP_DEST_LIMIT || pDp->dwMask & DP_SCALE)) { StretchBlt(hdc, rtDest.left, rtDest.top, rtDest.Width(), rtDest.Height(), m_Dib.GetSafeHdc(), rtSrc.left, rtSrc.top, rtSrc.Width(), rtSrc.Height(), SRCCOPY); } else { BitBlt(hdc, rtDest.left, rtDest.top, rtDest.Width(), rtDest.Height(), m_Dib.GetSafeHdc(), rtSrc.left, rtSrc.top, SRCCOPY); } } return TRUE; }
////////////////////////////////////////////////////////////////////////// // 画透明异形图的函数 // 注:在这里特别感谢CSDN网友: 黄凯飞, ID: hkf314 void CAnimateButton::AlphaBitmap(int nItem) { CDC* pDC = GetDC(); CDC TmpDC; TmpDC.CreateCompatibleDC(pDC); //当然,TmpBmp用来记录画的内容 CBitmap TmpBmp; TmpBmp.CreateCompatibleBitmap(pDC, m_aniBtnWidth, m_aniBtnHeight); TmpDC.SelectObject(&TmpBmp); //把按钮下的背景拷贝过来 TmpDC.BitBlt(0, 0, m_aniBtnWidth, m_aniBtnHeight, pDC, 0, 0, SRCCOPY); //把内存DC中的图像透明地画出来 AlphaBlend(TmpDC.m_hDC, 0, 0, m_aniBtnWidth, m_aniBtnHeight, m_pMemDC->m_hDC, nItem * m_aniBtnWidth, 0, m_aniBtnWidth, m_aniBtnHeight, m_bf); //填充异形图像以外的区域为mask色 CRgn rgn; rgn.CreateRectRgn(0, 0, m_aniBtnWidth, m_aniBtnHeight); rgn.CombineRgn(&rgn, CRgn::FromHandle(m_arBmpRgn[nItem]), RGN_DIFF); // TRACE("CRgn::FromHandle(m_arBmpRgn[nItem]): %d\n", nItem); CBrush maskBrh; maskBrh.CreateSolidBrush(m_clrTrans); TmpDC.FillRgn(&rgn, &maskBrh); // TmpDC.FillRgn(CRgn::FromHandle(m_arBmpRgn[nItem]), &maskBrh); //抠除mask色,直接画出来 ::TransparentBlt(pDC->m_hDC, 0, 0, m_aniBtnWidth, m_aniBtnHeight, TmpDC.m_hDC, 0, 0, m_aniBtnWidth, m_aniBtnHeight, m_clrTrans); // pDC->BitBlt(0, 0, m_aniBtnWidth, m_aniBtnHeight, &TmpDC, 0, 0, SRCCOPY); // pDC->FillRgn(CRgn::FromHandle(m_arBmpRgn[nItem]), &maskBrh); ReleaseDC(pDC); }
bool CDDB::PutBitmap( int x, int y, CDC *pDC, int xSrc, int ySrc, int dxSrc, int dySrc, int width, int height, DWORD dwRop, int alpha) { // Coordinate mode is not relative if ( m_CoordinateMode != CM_RELATIVE) GetRelativeCoordinate( &xSrc, &ySrc, &dxSrc, &dySrc); // Copy alphablended memory DC if ( alpha < 255) { BLENDFUNCTION blendFunc = { AC_SRC_OVER, 0, alpha, 0 }; // Copy memory bitmap AlphaBlend( m_DC, x, y, width, height, pDC->m_hDC, xSrc, ySrc, dxSrc, dySrc, blendFunc); } // Copy transparent memory DC else if ( dwRop == TRANSPARENT) { // Copy memory bitmap TransparentBlt( m_DC, x, y, width, height, pDC->m_hDC, xSrc, ySrc, dxSrc, dySrc, m_nTransColor); } // Copy memory DC else { // Copy memory bitmap m_DC.StretchBlt( x, y, width, height, pDC, xSrc, ySrc, dxSrc, dySrc, dwRop); } return true; }
BOOL ImageArray_DrawImage(IMAGE_ARRAY_DATA *iad, int pos, HDC hdcDest, int nXDest, int nYDest, BYTE Alpha) { if (hdcDest == NULL || pos < 0 || pos >= iad->nodes_size) return FALSE; EnterCriticalSection(&iad->cs); { int w, h, i; if (iad->width_based) { w = 0; h = 0; for (i = 0; i < pos; i++) { h += iad->nodes[i].height; } } else { h = 0; w = 0; for (i = 0; i < pos; i++) { w += iad->nodes[i].width; } } BLENDFUNCTION bf = { AC_SRC_OVER, 0, Alpha, AC_SRC_ALPHA }; AlphaBlend(hdcDest, nXDest, nYDest, iad->nodes[pos].width, iad->nodes[pos].height, iad->hdc, w, h, iad->nodes[pos].width, iad->nodes[pos].height, bf); } LeaveCriticalSection(&iad->cs); return FALSE; }
void ac::MirrorOrderAlpha(cv::Mat &frame) { cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); MirrorOrder(copy1); MirrorXorAll(copy2); AlphaBlend(copy1, copy2, frame, 0.5); MedianBlend(frame); }
void ac::OrigAndCurrentRandomX2(cv::Mat &frame) { cv::Mat copy1 = frame.clone(), copy2 = orig_frame.clone(); Random_Filter(copy1); Random_Filter(copy2); AlphaBlend(copy1, copy2, frame, 0.5); AddInvert(frame); }
void ac::MirrorLeftMirrorRightBlend(cv::Mat &frame) { cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); MirrorLeft(copy1); MirrorRight(copy2); AlphaBlend(copy1, copy2, frame, 0.5); AddInvert(frame); }
void ac::MirrorTopMirrorBottomBlend(cv::Mat &frame) { cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); MirrorTopToBottom(copy1); MirrorBottomToTop(copy2); AlphaBlend(copy1, copy2, frame, 0.5); AddInvert(frame); }
void ac::StretchSubFilter(cv::Mat &frame) { if(subfilter == -1 || draw_strings[subfilter] == "StretchSubFilter") return; static int w = 2, h = 2, speed = 5, dir = 100; if(dir == 1) { w += speed; h += speed; if(w > (frame.cols-1) || (h > frame.rows-1)) { dir = 0; w = frame.cols-2; h = frame.rows-2; } } else { w -= speed; h -= speed; if(w <= 64 || h <= 64) { dir = 1; w = 64; h = 64; } } cv::Mat copy1 = frame.clone(), copy2 = frame.clone(), reimage; cv::resize(frame, copy1, cv::Size(w, h)); CallFilter(subfilter, copy1); cv::resize(copy1, reimage, frame.size()); AlphaBlend(copy2, reimage, frame, 0.5); AddInvert(frame); }
void ac::Random_FilterX2(cv::Mat &frame) { cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); Random_Filter(copy1); Random_Filter(copy2); AlphaBlend(copy1, copy2, frame, 0.5); AddInvert(frame); }
void ac::MoveHighAndLow(cv::Mat &frame) { cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); LowToHigh(copy1); HighToLow(copy2); AlphaBlend(copy1, copy2, frame, 0.5); AddInvert(frame); }
void CLCDBitmap::OnDraw(CLCDGfxBase &rGfx) { if(m_hBitmap) { HDC hCompatibleDC = CreateCompatibleDC(rGfx.GetHDC()); HBITMAP hOldBitmap = (HBITMAP)SelectObject(hCompatibleDC, m_hBitmap); // If monochrome output, don't even bother with alpha blend if (LGLCD_BMP_FORMAT_160x43x1 == rGfx.GetLCDScreen()->hdr.Format) { BitBlt(rGfx.GetHDC(), 0, 0, m_sizeLogical.cx, m_sizeLogical.cy, hCompatibleDC, 0, 0, m_dwROP); } else { if(0.001f > fabs(1.0f - m_fZoom)) { BOOL b = FALSE; if(m_bAlpha) { BLENDFUNCTION opblender = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA}; b = AlphaBlend(rGfx.GetHDC(), 0, 0, m_sizeLogical.cx, m_sizeLogical.cy, hCompatibleDC, 0, 0, m_sizeLogical.cx, m_sizeLogical.cy, opblender); } else { BitBlt(rGfx.GetHDC(), 0, 0, m_sizeLogical.cx, m_sizeLogical.cy, hCompatibleDC, 0, 0, m_dwROP); } } else { if(m_bAlpha) { BLENDFUNCTION opblender = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA}; AlphaBlend(rGfx.GetHDC(), 0, 0, (int)(m_fZoom* m_sizeLogical.cx), (int)(m_fZoom*m_sizeLogical.cy), hCompatibleDC, 0, 0, m_sizeLogical.cx, m_sizeLogical.cy, opblender); } else { BLENDFUNCTION opblender = {AC_SRC_OVER, 0, 255, 0}; AlphaBlend(rGfx.GetHDC(), 0, 0, (int)(m_fZoom* m_sizeLogical.cx), (int)(m_fZoom*m_sizeLogical.cy), hCompatibleDC, 0, 0, m_sizeLogical.cx, m_sizeLogical.cy, opblender); } } } // restores SelectObject(hCompatibleDC, hOldBitmap); DeleteDC(hCompatibleDC); } }
BOOL ScreenSnapshot::snapshotScreen() { if (m_hMemDC) { DeleteObject(m_hMemBitmap); DeleteDC(m_hMemDC); m_hMemBitmap = NULL; m_hMemDC = NULL; } if (m_hBkgMemDC) { DeleteObject(m_hBkBitmap); DeleteDC(m_hBkgMemDC); m_hBkBitmap = NULL; m_hBkgMemDC = NULL; } if (m_hDrawMemDC) { DeleteObject(m_hDrawBitmap); DeleteDC(m_hDrawMemDC); m_hDrawBitmap = NULL; m_hDrawMemDC = NULL; } // HWND hDesktopWnd = GetDesktopWindow(); HDC hScreenDC = GetDC(hDesktopWnd); RECT rc = { 0 }; GetWindowRect(hDesktopWnd, &rc); int cx = rc.right - rc.left; int cy = rc.bottom - rc.top; HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, cx, cy); m_hMemDC = CreateCompatibleDC(hScreenDC); HGDIOBJ hOldBitmap = SelectObject(m_hMemDC, (HGDIOBJ)hBitmap); BitBlt(m_hMemDC, 0, 0, cx, cy, hScreenDC, 0, 0, SRCCOPY); m_hBkgMemDC = CreateCompatibleDC(hScreenDC); HBITMAP hBkgBitmap = CreateCompatibleBitmap(hScreenDC, cx, cy); SelectObject(m_hBkgMemDC, (HGDIOBJ)hBkgBitmap); BitBlt(m_hBkgMemDC, 0, 0, cx, cy, hScreenDC, 0, 0, SRCCOPY); HDC hMaskDC = CreateCompatibleDC(hScreenDC); HBITMAP hMaskBitmap = CreateCompatibleBitmap(hScreenDC, cx, cy); SelectObject(hMaskDC, (HGDIOBJ)hMaskBitmap); BLENDFUNCTION ftn = { AC_SRC_OVER, 0, 100, 0 }; AlphaBlend(m_hBkgMemDC, 0, 0, cx, cy, hMaskDC, 0, 0, cx, cy, ftn); DeleteObject(hMaskBitmap); DeleteDC(hMaskDC); m_hDrawMemDC = CreateCompatibleDC(hScreenDC); HBITMAP hDrawBitmap = CreateCompatibleBitmap(hScreenDC, cx, cy); SelectObject(m_hDrawMemDC, hDrawBitmap); ReleaseDC(hDesktopWnd, hScreenDC); return TRUE; }
void ac::OrigBlendSubFilter(cv::Mat &frame) { if(subfilter == -1 || draw_strings[subfilter] == "OrigBlendSubFilter" || orig_frame.empty() || orig_frame.size() != frame.size()) return; cv::Mat copy1 = frame.clone(), copy2 = orig_frame.clone(); CallFilter(subfilter, copy2); AlphaBlend(copy1, copy2, frame, 0.5); AddInvert(frame); }
void ac::ImageLofiAlphaBlend(cv::Mat &frame) { if(blend_set == false) return; cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); ImageLoFi(copy1); AlphaBlend(copy1, copy2, frame, 0.5); AddInvert(frame); }
void ac::SmoothTrailsBlend(cv::Mat &frame) { static MatrixCollection<16> collection; cv::Mat copyf = frame.clone(); cv::Mat copyi = frame.clone(); Smooth(copyf, &collection); AlphaBlend(copyf, copyi, frame, 0.5); AddInvert(frame); }
void ac::MirrorSwitchSubFilter(cv::Mat &frame) { if(subfilter == -1 || draw_strings[subfilter] == "MirrorSwitchSubFilter") return; cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); MirrorSwitch(copy1); AlphaBlend(copy1, copy2, frame, 0.5); CallFilter(subfilter, frame); AddInvert(frame); }
void ac::ImageHighToLowAlpha(cv::Mat &frame) { if(blend_set == false) return; cv::Mat copy1 = frame.clone(), reimage; cv::resize(blend_image, reimage, frame.size()); HighToLow(reimage); AlphaBlend(copy1, reimage, frame, 0.5); AddInvert(frame); }
void ac::Random_FilterSubFilter(cv::Mat &frame) { if(subfilter == -1 || draw_strings[subfilter] == "Random_FilterSubFilter") return; cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); Random_Filter(copy1); CallFilter(subfilter, copy2); AlphaBlend(copy1, copy2, frame, 0.5); AddInvert(frame); }
void ac::ReverseSubFilterBlend(cv::Mat &frame) { if(subfilter == -1 || ac::draw_strings[subfilter] == "ReverseSubFilterBlend") return; cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); CallFilter(subfilter, copy1); Reverse(copy2); CallFilter(subfilter, copy2); AlphaBlend(copy1, copy2, frame, 0.5); }
void ac::ShuffleAlphaSubFilter(cv::Mat &frame) { if(subfilter == -1 || ac::draw_strings[subfilter] == "ShuffleAlphaSubFilter") return; cv::Mat copyf = frame.clone(), copyi = frame.clone(); ShuffleAlpha(copyf); CallFilter(subfilter, copyi); AlphaBlend(copyf, copyi, frame, 0.5); AddInvert(frame); }
void EmoticonsSelectionLayout::DrawEmoticon(HDC hdc, int index, RECT fullRc) { Emoticon *e = ssd->module->emoticons[index]; int width, height; GetEmoticonSize(e, width, height); RECT rc = fullRc; rc.left += (rc.right - rc.left - width) / 2; rc.top += (rc.bottom - rc.top - height) / 2; rc.right = rc.left + width; rc.bottom = rc.top + height; if (e->img == NULL || e->img->img == NULL) { if (e->texts.getCount() > 0) { DrawEmoticonText(hdc, e->texts[0], rc); } else { DrawEmoticonText(hdc, e->description, rc); } } else { HDC hdc_img = CreateCompatibleDC(hdc); HBITMAP old_bmp = (HBITMAP) SelectObject(hdc_img, e->img->img); if (e->img->transparent) { BLENDFUNCTION bf = {0}; bf.SourceConstantAlpha = 255; bf.AlphaFormat = AC_SRC_ALPHA; AlphaBlend(hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, hdc_img, 0, 0, rc.right - rc.left, rc.bottom - rc.top, bf); } else { BitBlt(hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, hdc_img, 0, 0, SRCCOPY); } SelectObject(hdc_img, old_bmp); DeleteDC(hdc_img); } if (selection == index) { rc = fullRc; rc.left -= 2; rc.right += 2; rc.top -= 2; rc.bottom += 2; FrameRect(hdc, &rc, (HBRUSH) GetStockObject(GRAY_BRUSH)); } }