windows下利用句柄为指定窗口填充颜色

windows下利用句柄为指定窗口填充颜色

有时候我们需要通过句柄来对指定的窗口进行颜色填充,刚开始可能会想到使用setbkcolor(),setbkmode()函数来实现。但最后发现并不能实现。search了一下才知道

这个函数填补了使用CreatePen函数创建的钢笔绘制的样式线之间的空白;它没有填充使用由ExtCreatePen函数创建的钢笔所绘制的样式线之间的间隙。SetBkColor函数还设置了TextOut和ExtTextOut的背景颜色。

如果背景模式是不透明的,则使用背景色来填充不同样式的线条之间的间隙,在笔刷中产生的间隙和字符单元格之间的空隙。当将位图从颜色转换为单色时,背景颜色也会被使用,反之亦然。

也就说不能使用这个函数来进行整个屏幕颜色的填充,所以直接使用画刷来实现。代码如下:

void SetBlackColor(HWND hwnd)

{ RECT rect;

HDC hdc;

HBRUSH rush;

hdc = GetDC(hwnd);

rush = CreateSolidBrush(RGB(127,127,127));

//rush = (HBRUSH)

GetStockObject(NULL_BRUSH);

GetClientRect(hwnd, &rect);

//crDebug("##Test The Set Color Rect(%d, %d, %d, %d)", rect.left, rect.top, rect.right, rect.bottom);

FillRect(hdc, &rect, rush);

DeleteObject(rush);

ReleaseDC(hwnd, hdc);

}

很多时候我么可能还需要获得某个窗口的句柄,使用spy++可以查看windows下窗口的句柄。具体步骤:窗口查找->将查找程序工具图标移动到窗口上即可。这里我们可以通过窗口的标题和类来获得窗口的句柄(使用FindWindow函数),如果窗口的类名和窗口的名相同并且在相同的父窗口下则可以通过FindWindowExA函数一层一层的定位子窗口,具体可以参看该函数的文档。

这是我的窗口:

刷屏后(使用的是GetClientRect函数,所以取得的是客户区rect,注意与GetWindowRect的区别):

这是我将子窗口进行颜色填充的代码,通过FindWindowExA函数进行一层一层的定位,当然对于相同的类和标题的时候我们可以用循环来解决,我这里方便大家了解FindWindowExA的用法。

 RECT rect;
 HWND hwnd=FindWindow("CabinetWClass",NULL);
 HWND play = FindWindowExA(hwnd,NULL,"ShellTabWindowClass",NULL);
 play = FindWindowExA(play,NULL,"DUIViewWndClassName",NULL);
 play = FindWindowExA(play,NULL,"DirectUIHWND",NULL);
 HWND t=FindWindowExA(play,NULL,"CtrlNotifySink",NULL);
 t=FindWindowExA(play,t,"CtrlNotifySink",NULL);
 t=FindWindowExA(play,t,"CtrlNotifySink",NULL);
 t=FindWindowExA(t,NULL,"SHELLDLL_DefView",NULL);
 t=FindWindowExA(t,NULL,"DirectUIHWND",NULL);
 HDC hdc; HBRUSH rush; hdc = GetDC(t);
 rush = CreateSolidBrush(RGB(0,0,0));
 //rush = (HBRUSH)GetStockObject(NULL_BRUSH);
 GetClientRect(t, &rect);
 //crDebug("##Test The Set Color Rect(%d, %d, %d, %d)", rect.left, rect.top, rect.right, rect.bottom);
 FillRect(hdc, &rect, rush);
 DeleteObject(rush);
 ReleaseDC(hwnd, hdc);

效果图如下:

如果不是客户区全填充的话,可以试一下


SelectObject(hdc, rush); // 指定画刷
Rectangle(hdc,80, 50, 300, 200);

效果如下(灵活自定义):

用图片填充窗口:


void MyLoadImage(HWND hwnd)

{ HDC   hdc;

HBITMAP hbm;

HDC hdcBits;

BITMAP bm;

hdc   = GetDC(hwnd);

hbm=(HBITMAP)LoadImage(0,"C:\\Users\\tom\\Desktop\\0.bmp",IMAGE_BITMAP,0,0,LR_DEFAULTSIZE|LR_LOADFROMFILE);

if (hbm) {

hdcBits = CreateCompatibleDC(hdc);

GetObject (hbm, sizeof(BITMAP), &bm);

SelectObject(hdcBits,hbm);

// StretchBlt函数也可以

BitBlt(hdc,0,0,bm.bmWidth, bm.bmHeight,hdcBits,0,0,SRCCOPY);

DeleteDC(hdcBits);

DeleteObject(hbm);

}

ReleaseDC(hwnd,hdc);

}

效果:略

如果要循环绘制,更好还是结合WM_PAINT使用beginpaint和endpaint利用消息机制来绘制效率和效果会比上面的好很多。

发表评论

电子邮件地址不会被公开。 必填项已用*标注