关于DirectUI界面设计 技术总结,欢迎讨论和交流,不断更新

https://files.cnblogs.com/ququer/TYPlayer.rar

1.关于窗体变色

这个很多人都喜欢把:

效果:

image_thumb[1]  image_thumb[3]  image_thumb[5]  image_thumb[7]

原理说白了,就是hdc 4个通道的处理:

#define   PCL_R(p)   (((RGBQUAD*)(p))->rgbRed)
#define   PCL_G(p)   (((RGBQUAD*)(p))->rgbGreen)
#define   PCL_B(p)   (((RGBQUAD*)(p))->rgbBlue)
#define   PCL_A(p)   (((RGBQUAD*)(p))->rgbReserved)

template<class T> inline const T& ttMax (const T& _X, const T& _Y) {return (_X < _Y ? _Y : _X);}
template<class T> inline const T& ttMin (const T& _X, const T& _Y) {return (_Y < _X ? _Y : _X);}
template<class T> inline void ttSwap (T& t1, T& t2) { const T tmp=t1 ; t1=t2 ; t2=tmp ;}
template<class T> inline T ttSquare (const T& t) {return t*t ;}
template<class T> inline T ttClamp (const T& t, const T& tLow, const T& tHigh) {return ttMax (tLow, ttMin (tHigh, t)) ;}
int ttClamp0255 (int n) {    return ttClamp (n, 0, 0xFF);    } //0-255

BITMAPINFO bi = {0};
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bIsOk = GetDIBits(m_memGDC->m_hBkDc, m_memGDC->m_hBitmap, 0, 0, NULL, &bi, DIB_RGB_COLORS);    assert(bIsOk==1);
bi.bmiHeader.biCompression = BI_RGB;
bi.bmiHeader.biPlanes = 1;
RGBQUAD *pBits = (RGBQUAD*)malloc(iWidth * iHeigh * (bi.bmiHeader.biBitCount/8) * sizeof(BYTE));
bIsOk = GetDIBits(m_memGDC->m_hBkDc, m_memGDC->m_hBitmap, 0, iHeigh, (LPVOID)pBits, &bi, DIB_RGB_COLORS);
assert(bIsOk==1);

RGBQUAD clAve = GetBitRandAveRGB(pBits, iWidth * iHeigh, 25);//计算伪平均颜色
for(int i=0; i != iWidth * iHeigh ; ++i)
{   
    if(IsCHGColor)
    {
        PCL_R(&pBits[i]) = ttClamp0255(PCL_R(&pBits[i]) + m_ChR - PCL_R(&clAve));
        PCL_G(&pBits[i]) = ttClamp0255(PCL_G(&pBits[i]) + m_ChG - PCL_G(&clAve));
        PCL_B(&pBits[i]) = ttClamp0255(PCL_B(&pBits[i]) + m_ChB - PCL_B(&clAve));
    }
    if(PCL_R(&pBits[i])==0 && PCL_G(&pBits[i])==0 && PCL_B(&pBits[i])==0)//防止完全透明
    {
        PCL_R(&pBits[i]) = 1;
        PCL_G(&pBits[i]) = 1;
        PCL_B(&pBits[i]) = 1;
    }
    PCL_A(&pBits[i]) = m_ChA;
}
SetDIBits(m_memGDC->m_hBkDc, m_memGDC->m_hBitmap, 0, iHeigh, (LPVOID)pBits, &bi, DIB_RGB_COLORS);

更换四个通道的颜色只用改m_ChR  m_ChG m_ChB m_ChA

说白了就是网上有一大堆的什么jpg开源的图片处理技术偷点代码就做了。

下面我要问几个问题:请高手回答:

1.如何提高效率

2.谁能改进一下,谢谢,我的邮箱:acmfan@msn.cn

2.关于png带透明通道的图片拉伸

A:imageB:image

如何把B拉伸成A,67TR6P2BBT4[9C_}XIE)HCU用StretchBlt吧 ,可以拉伸时带透明通道的处理

像这样:

int a = 7;
int b = 7;
//四角拷贝
StretchBlt(hdc, 0, 0, a, b, hBkDc, 0, 0, a, b, SRCCOPY);
StretchBlt(hdc, dwt-a, 0, a, b, hBkDc, swt-a, 0, a, b, SRCCOPY);
StretchBlt(hdc, 0, dht-b, a, b, hBkDc, 0, sht-b, a, b, SRCCOPY);
StretchBlt(hdc, dwt-a, dht-b, a, b, hBkDc, swt-a, sht-b, a, b, SRCCOPY);
//边界拉伸
int x=7;
int y=7;
StretchBlt(hdc, x, 0, dwt-2*x, y, hBkDc, x, 0, swt-2*x, y, SRCCOPY);
StretchBlt(hdc, x, dht-y, dwt-2*x, y, hBkDc, x, sht-y, swt-2*x, y, SRCCOPY);

StretchBlt(hdc, dwt-x, y, x, dht-2*y, hBkDc, swt-x, y, x, sht-2*y, SRCCOPY);
StretchBlt(hdc, 0, y, x, dht-2*y, hBkDc, 0, y, x, sht-2*y, SRCCOPY);
//拉伸中间区域
StretchBlt(hdc, x, y, dwt-2*x, dht-2*y, hBkDc, x, y, swt-2*x, sht-2*y, SRCCOPY);

在用StretchBlt前 还可以设置拉伸属性哦:SetStretchBltMode(hDc, HALFTONE);(这个函数是可以秒杀几个gdi+的函数的B32W29IZXVT_YVSGMHJ}YYU[4]

3.关于窗体动画的看法

@489C`P93PMP68E{$9DC5EF以下全是个人看法:

如果您的架构支持timer,如果您的窗体支持透明度更改,您就可以实现几乎70%任何动画了

如果您用到了D3D,几乎可以秒杀所有您看到的动画了。

如果您用到了webkit+D3D,您就可以用D3D渲染flash,请您把您的源代码发给我,邮箱acmfan@msn.cnB32W29IZXVT_YVSGMHJ}YYU[6]

4.边框绘制

下面的代码暂时不用了(其实还是很有用处的) 存着自己看

其实最好的画边框的方法是 贴png框(带阴影),上面代码已经透露了 不懂可以问我QQ:820156394

colorAve = GetHdcRandAveRGB(m_memGDC->m_hBkDc, m_memGDC->m_iWidth, m_memGDC->m_iHeight, 25);
Graphics graph(m_memGDC->m_hBkDc);
RGBQUAD cl;
PCL_R(&cl) = GetRValue(colorAve);
PCL_G(&cl) = GetGValue(colorAve);
PCL_B(&cl) = GetBValue(colorAve);
PCL_A(&cl) = m_ChA;
DrawRoundRectange(&graph, cl, 1, 1, iWidth-4, iHeigh-4, 8);//内框
double k = 0.66;
PCL_R(&cl) = ttClamp0255(PCL_R(&cl)*k);
PCL_G(&cl) = ttClamp0255(PCL_G(&cl)*k);
PCL_B(&cl) = ttClamp0255(PCL_B(&cl)*k);
PCL_A(&cl) = m_ChA;
DrawRoundRectange(&graph, cl, 0, 0, iWidth-2, iHeigh-2, 8);//外框

// gdi+画一个圆角的矩形
void DrawRoundRectange(Graphics *graph, RGBQUAD cl, int x, int y, int width, int height, int r)
{
    graph->SetSmoothingMode(SmoothingModeHighQuality );
    Pen pen(Color(PCL_A(&cl), PCL_R(&cl),PCL_G(&cl),PCL_B(&cl)));
    int r2=r*2;
    graph->DrawLine(&pen, x+r, y,        x+width-r, y);

    graph->DrawLine(&pen, x+r, y+height,x+width-r, y+height);

    graph->DrawLine(&pen, x,        y+r, x,            y+height-r);
    graph->DrawLine(&pen, x+width,    y+r, x+width,    y+height-r);
   
    graph->DrawArc(&pen, x,            y,            r2,r2,180,90);
    graph->DrawArc(&pen, x+width-r2,y+height-r2,r2,r2,360,90);
    graph->DrawArc(&pen, x+width-r2,y,            r2,r2,270,90);
    graph->DrawArc(&pen, x,            y+height-r2,r2,r2,90,90);
}

// gdi画一个圆角的矩形
void DrawRoundRectange(HDC hdc, COLORREF cl, int x, int y, int iWidth, int iHeigh, int r)
{
    RECT rcRect = {x, y, iWidth, iHeigh};
    HBRUSH brush = CreateSolidBrush(cl);
    FrameRect(hdc, &rcRect, brush);
    HPEN pen = CreatePen(PS_SOLID, 1, cl);
    HPEN oldpen = (HPEN)SelectObject(hdc, pen);
    int r2 = r*2;
    Arc(hdc, x, y, x+r2, y+r2, x+r, y, x, y+r);
    Arc(hdc, x+iWidth-r2, y, x+iWidth, y+r2, x+iWidth, y+r, x+iWidth-r, y);
    Arc(hdc, x, y+iHeigh-r2, x+r2, y+iHeigh, x, y+iHeigh-r, x+r, y+iHeigh);
    Arc(hdc, x+iWidth-r2, y+iHeigh-r2, x+iWidth, y+iHeigh, x+iWidth-r, y+iHeigh, x+iWidth, y+iHeigh-r);
    SelectObject(hdc, oldpen);
}

5.关于gdi和gdi+混合渲染的原则:

一般出现的问题是很诡异的,代码没有错误,但就是画出来的东西及其诡异,你最需要注意,混合渲染的时候gdi+对象必须画完就释放就好了,换句话说,不能gdi+对象没有释放就用gdi函数乱画一同,

所以可以这样
{

gdi+对象绘制

}

6.关于消息分发:

从主窗口分发消息,用一个对象管理器管理所有控件,控件和对象管理器均无句柄,

窗口对话框用类的子类化处理

对象分发消息主要按 控件的可见和disable属性 是否捕获鼠标 是否有焦点 以及控件状态

所有控件继承于CDUIWnd,用多态实现公用方法

每个控件都可以有n种渲染方式,这个在控件类中实现

对象管理器可维护一个timer列表。

对象管理器可维护一个对象列表。

7.关于未来的设想:

想添加 IE组件管理 用微软js引擎控制界面逻辑,还不是很了解

xml界面设计,这个还好

毛玻璃效果,不知道原理

edit控件,现在还嫌它太麻烦,没敢动它

posted @ 2011-08-11 18:41  Vegetable Bird  阅读(1118)  评论(0编辑  收藏  举报