在网上查了好多资料,各个实现 方法都不一样。这里自己总结一下学习体会。
界面是powerbuilder9中的控件,使用子类化函数在DLLk上处理,我想作一套通用的界面接口,
这样可以在VC+PB9一起使用.
1.蓝色底色由WM_ERASEBKGND控制,这个RECT 比白色刷子的大2个象素,正好用于3D边框绘制。
白色刷子是由WM_CTLCOLOREDIT的返回值控制的。
2.字体颜色由WM_CTLCOLOREDIT消息控制
- SetBkMode(hdc,TRANSPARENT);可以控制白底红字中的白色底色,设置为透明模式,就和底色刷子一样了。
- SetTextColor(hdc,RGB(255,0,0));这个可以控制字体的颜色 红色
- 返回值,是一个底色刷子。 return (LRESULT) (HBRUSH)GetStockObject(BLACK_BRUSH); //黑色
如果WM_ERASEBKGND消息中已经绘制好了底色(蓝色),就返回NULL_BRUSH。不用重复绘制。
3.直接使用WM_NCPAINT消息进行绘制边框
底色是黑的,边框是蓝色的。最外层3D边框是2相像素。第1个图是有SCROLLBAR风格的。
if(uMsg ==WM_NCPAINT )
{
HPEN hPenBorder = 0;
hPenBorder = CreatePen(BS_SOLID,1,RGB(0,0,255));
HDC hdc = GetWindowDC(hWnd);
RECT rc;
GetWindowRect(hWnd,&rc);
int w = rc.right - rc.left ;
int h = rc.bottom - rc.top ;
POINT pt ;
pt.x = rc.left ;
pt.y = rc.top ;
ScreenToClient(hWnd,&pt);
rc.left = pt.x +2;
rc.top = pt.y +2;
rc.right = pt.x + w +2;
rc.bottom = pt.y + h +2 ;
SelectObject(hdc,hPenBorder);
SelectObject(hdc,(HBRUSH)GetStockObject(BLACK_BRUSH));
Rectangle(hdc, rc.left ,rc.top,rc.right,rc.bottom );
ReleaseDC(hWnd,hdc);
DeleteObject(hPenBorder);
return 1 ;
}
如果要显示系统默认的底框,可以先调用CallWindowProc来执行一次默认的绘制,然后再执行自己的绘制方法,
如图:系统默认的滚动条出现了。边框也有。
如代码:
if(uMsg ==WM_NCPAINT )
{
if(PfnWndAddress)
{
lResult = CallWindowProc(PfnWndAddress,hWnd,uMsg,wParam,lParam);
}
HPEN hBorder = CreatePen(BS_SOLID,1,RGB(255,255,255));
HPEN hPenBorder = 0;
hPenBorder = CreatePen(BS_SOLID,1,RGB(0,0,255));
HDC hdc = GetWindowDC(hWnd);
RECT rc;
GetWindowRect(hWnd,&rc);
int w = rc.right - rc.left ;
int h = rc.bottom - rc.top ;
POINT pt ;
pt.x = rc.left ;
pt.y = rc.top ;
ScreenToClient(hWnd,&pt);
rc.left = pt.x +2;
rc.top = pt.y +2;
rc.right = pt.x + w +2;
rc.bottom = pt.y + h +2 ;
SelectObject(hdc,hPenBorder);
SelectObject(hdc,(HBRUSH)GetStockObject(NULL_BRUSH));
Rectangle(hdc, rc.left ,rc.top,rc.right,rc.bottom );
SelectObject(hdc,hBorder);
rc.left +=1;
rc.top +=1;
rc.right -=1;
rc.bottom -=1;
Rectangle(hdc, rc.left ,rc.top,rc.right,rc.bottom );
DeleteObject(hPenBorder);
DeleteObject(hBorder);
ReleaseDC(hWnd,hdc);
return 0 ;
}