分享
 
 
 

编程技巧15法之二

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

1. 如何在指定矩形框内水平/垂直显示多行文字

///////////////////////////////////////////////////////

//说明:

// 在矩形框中水平或垂直显示多行文字,jingzhou xu.

// lMode: 排列方式,0:水平方式; 1:垂直对齐

// lHori: 水平对齐方式, 0:左对齐; 1:居中; 2:右对齐; 3:自定义

// lVert: 垂直对齐方式, 0:顶对齐; 1:居中; 2:底对齐; 3:自定义

///////////////////////////////////////////////////////

CRect DrawTitleInRect(CDC *pDC, CString szString, LPRECT lpRect, long lMode, long lHori, long lVert)

{

TEXTMETRIC tm;

pDC->GetTextMetrics(&tm);

int tmpWidth=tm.tmAveCharWidth, tmpHeight=tm.tmHeight;

CRect rcInner(lpRect);

if(lMode==0)

{

rcInner.left+=tmpWidth;

rcInner.right-=tmpWidth;

rcInner.top-=tmpWidth;

rcInner.bottom+=tmpWidth;

}

if(lMode==1)

{

rcInner.left+=tmpWidth;

rcInner.right=rcInner.left+tmpWidth;

rcInner.top-=tmpWidth;

rcInner.bottom+=tmpWidth;

}

pDC->DrawText(szString, rcInner,DT_CALCRECT);

switch(lHori)

{

case 0:

break;

case 1:

{

long xOutCent=(lpRect->right+lpRect->left)/2;

long xInnCent=(rcInner.right+rcInner.left)/2;

rcInner.left+=(xOutCent-xInnCent);

rcInner.right+=(xOutCent-xInnCent);

}

break;

case 2:

{

long lInWidth=rcInner.right-rcInner.left;

rcInner.right=lpRect->right-tmpWidth;

rcInner.left=rcInner.right-lInWidth;

}

break;

default:

break;

}

switch(lVert)

{

case 0:

break;

case 1:

{

long yOutCent=(lpRect->bottom+lpRect->top)/2;

long yInnCent=(rcInner.bottom+rcInner.top)/2;

rcInner.top-=(yInnCent-yOutCent);

rcInner.bottom-=(yInnCent-yOutCent);

}

break;

case 2:

{

long lInHeigh=rcInner.top-rcInner.bottom;

rcInner.bottom=lpRect->bottom+tmpWidth;

rcInner.top=rcInner.bottom+lInHeigh;

}

break;

default:

break;

}

//---------------------------------------------------------------------------------------------

//功能:根据新、老矩形,重新计算行数,使文字多行显示,jingzhou xu

//---------------------------------------------------------------------------------------------

//一行中最大字符数

int nMaxLineChar = abs(lpRect->right - lpRect->left) / tmpWidth ;

//记录当前行的宽度

short theLineLength=0;

//记录当前行中汉字字节数,以防止将一半汉字分为两行

unsigned short halfChinese=0;

for(int i=0; i<=szString.GetLength()-1; i++)

{

if(((unsigned char)szString.GetAt(i) == 0x0d) && ((unsigned char)szString.GetAt(i+1) == 0x0a))

theLineLength=0;

//大于0xa1的字节为汉字字节

if((unsigned char)szString.GetAt(i) >= 0xA1)

halfChinese++;

theLineLength++;

//如果行宽大于每行最大宽度,进行特殊处理

if(theLineLength > nMaxLineChar)

{

//防止将一个汉字分为两行,回溯

if(halfChinese%2)

{

szString.Insert(i,(unsigned char)0x0a);

szString.Insert(i,(unsigned char)0x0d);

}

else

{

szString.Insert(i-1,(unsigned char)0x0a);

szString.Insert(i-1,(unsigned char)0x0d);

}

theLineLength = 0;

}

}

//重新计算矩形边界范围

// int tmpLine = int(abs(szString.GetLength()*tmpWidth / abs(lpRect->right - lpRect->left)-0.5));

// tmpLine += (szString.GetLength()*tmpWidth % abs(lpRect->right - lpRect->left))? 1 : 0;

// if(tmpLine == 0)

// tmpLine = 1;

if(rcInner.bottom > lpRect->bottom)

rcInner.bottom = lpRect->bottom;

if(rcInner.top < lpRect->top)

rcInner.top = lpRect->top;

//---------------------------------------------------------------------------------------------

if(lHori==0)

pDC->DrawText(szString, rcInner, DT_WORDBREAK|DT_LEFT);

else if(lHori==1)

pDC->DrawText(szString, rcInner, DT_WORDBREAK|DT_CENTER);

else if(lHori==2)

pDC->DrawText(szString, rcInner, DT_WORDBREAK|DT_RIGHT);

return rcInner;

}

2. 如何在指定矩形中旋转显示文字

///////////////////////////////////////////////////////

//说明:

// 在矩形框中旋转方式显示文字,jingzhou xu

//参数:

// pDC: DC指针

// str: 显示文字

// rect: 显示范围

// angle: 旋转角度

// nOptions: ExtTextOut()中相应设置<ETO_CLIPPED 和 ETO_OPAQUE>

///////////////////////////////////////////////////////

void DrawRotatedText(CDC* pDC, const CString str, CRect rect,

double angle, UINT nOptions)

{

//按比例转换角度值

double pi = 3.141592654;

double radian = pi * 2 / 360 * angle;

//获取显示文字中心点

CSize TextSize = pDC->GetTextExtent(str);

CPoint center;

center.x = TextSize.cx / 2;

center.y = TextSize.cy / 2;

//计算显示文字新的中心点

CPoint rcenter;

rcenter.x = long(cos(radian) * center.x - sin(radian) * center.y);

rcenter.y = long(sin(radian) * center.x + cos(radian) * center.y);

//绘制文字

pDC->SetTextAlign(TA_BASELINE);

pDC->SetBkMode(TRANSPARENT);

pDC->ExtTextOut(rect.left + rect.Width() / 2 - rcenter.x,

rect.top + rect.Height() / 2 + rcenter.y,

nOptions, rect, str, NULL);

}

3. 如何将32 x 32像素图标转换为16 x 16像素值的图标

HICON Convert32x32IconTo16x16(HICON h32x32Icon)

{

HDC hMainDC, hMemDC1, hMemDC2;

HICON h16x16Icon;

BITMAP bmp;

HBITMAP hOldBmp1, hOldBmp2;

ICONINFO IconInfo32x32, IconInfo16x16;

GetIconInfo(h32x32Icon, &IconInfo32x32);

hMainDC = ::GetDC(m_hWnd);

hMemDC1 = CreateCompatibleDC(hMainDC);

hMemDC2 = CreateCompatibleDC(hMainDC);

GetObject(IconInfo32x32.hbmColor, sizeof(BITMAP), &bmp);

IconInfo16x16.hbmColor = CreateBitmap( 16, 16,

bmp.bmPlanes,

bmp.bmBitsPixel,

NULL);

hOldBmp1 = (HBITMAP) SelectObject( hMemDC1,

IconInfo32x32.hbmColor);

hOldBmp2 = (HBITMAP) SelectObject( hMemDC2,

IconInfo16x16.hbmColor);

StretchBlt(hMemDC2,

0, 0,

16, 16,

hMemDC1,

0, 0,

32, 32,

SRCCOPY

);

GetObject(IconInfo32x32.hbmMask, sizeof(BITMAP), &bmp);

IconInfo16x16.hbmMask = CreateBitmap( 16, 16,

bmp.bmPlanes,

bmp.bmBitsPixel,

NULL);

SelectObject(hMemDC1, IconInfo32x32.hbmMask);

SelectObject(hMemDC2, IconInfo16x16.hbmMask);

StretchBlt(hMemDC2,

0, 0,

16, 16,

hMemDC1,

0, 0,

32, 32,

SRCCOPY

);

SelectObject(hMemDC1, hOldBmp1);

SelectObject(hMemDC2, hOldBmp2);

IconInfo16x16.fIcon = TRUE;

h16x16Icon = CreateIconIndirect(&IconInfo16x16);

DeleteObject(IconInfo32x32.hbmColor);

DeleteObject(IconInfo16x16.hbmColor);

DeleteObject(IconInfo32x32.hbmMask);

DeleteObject(IconInfo16x16.hbmMask);

DeleteDC(hMemDC1);

DeleteDC(hMemDC2);

::ReleaseDC(m_hWnd, hMainDC);

return h16x16Icon;

}

4. 如何建立一个灰度级图标

HICON CreateGrayscaleIcon(HICON hIcon)

{

HICON hGrayIcon = NULL;

HDC hMainDC = NULL,

hMemDC1 = NULL,

hMemDC2 = NULL;

BITMAP bmp;

HBITMAP hOldBmp1 = NULL,

hOldBmp2 = NULL;

ICONINFO csII, csGrayII;

BOOL

bRetValue = FALSE;

bRetValue = ::GetIconInfo(hIcon, &csII);

if (bRetValue == FALSE) return NULL;

hMainDC = ::GetDC(m_hWnd);

hMemDC1 = ::CreateCompatibleDC(hMainDC);

hMemDC2 = ::CreateCompatibleDC(hMainDC);

if (hMainDC == NULL ||

hMemDC1 == NULL ||

hMemDC2 == NULL)

return NULL;

if (::GetObject(csII.hbmColor,

sizeof(BITMAP), &

amp;bmp))

{

csGrayII.hbmColor =

::CreateBitmap(csII.xHotspot*2,

csII.yHotspot*2,

bmp.bmPlanes,

bmp.bmBitsPixel,

NULL);

if (csGrayII.hbmColor)

{

hOldBmp1 =

(HBITMAP)::SelectObject(hMemDC1,

csII.hbmColor);

hOldBmp2 =

(HBITMAP)::SelectObject(hMemDC2,

csGrayII.hbmColor);

::BitBlt(hMemDC2, 0, 0, csII.xHotspot*2,

csII.yHotspot*2, hMemDC1, 0, 0,

SRCCOPY);

DWORD dwLoopY = 0, dwLoopX = 0;

COLORREF crPixel = 0;

BYTE byNewPixel = 0;

for (dwLoopY = 0; dwLoopY < csII.yHotspot*2; dwLoopY++)

{

for (dwLoopX = 0; dwLoopX < csII.xHotspot*2; dwLoopX++)

{

crPixel = ::GetPixel(hMemDC2, dwLoopX, dwLoopY);

byNewPixel = (BYTE)((GetRValue(crPixel) * 0.299) +

(GetGValue(crPixel) * 0.587) +

(GetBValue(crPixel) * 0.114));

if (crPixel) ::SetPixel(hMemDC2,

dwLoopX,

dwLoopY,

RGB(byNewPixel,

byNewPixel,

byNewPixel));

} // for

} // for

::SelectObject(hMemDC1, hOldBmp1);

::SelectObject(hMemDC2, hOldBmp2);

csGrayII.hbmMask = csII.hbmMask;

csGrayII.fIcon = TRUE;

hGrayIcon = ::CreateIconIndirect(&csGrayII);

} // if

::DeleteObject(csGrayII.hbmColor);

//::DeleteObject(csGrayII.hbmMask);

} // if

::DeleteObject(csII.hbmColor);

::DeleteObject(csII.hbmMask);

::DeleteDC(hMemDC1);

::DeleteDC(hMemDC2);

::ReleaseDC(m_hWnd, hMainDC);

return hGrayIcon;

}

5. 如何按指定角度旋转显示内存位图(用法和BitBlt类似)

void RotBlt(HDC destDC, int srcx1, int srcy1, int srcx2, int srcy2,

HDC srcDC , int destx1, int desty1 ,int thetaInDegrees ,DWORD mode)

{

double theta = thetaInDegrees * (3.14159/180);

//原图像原始大小

int width = srcx2 - srcx1;

int height = srcy2 - srcy1;

//原图像中心点

int centreX = int(float(srcx2 + srcx1)/2);

int centreY = int(float(srcy2 + srcy1)/2);

//判断出图像可以沿任意方向旋转的矩形框

if(width>height)height = width;

else

width = height;

HDC memDC = CreateCompatibleDC(destDC);

HBITMAP memBmp = CreateCompatibleBitmap(destDC, width, height);

HBITMAP obmp = (HBITMAP) SelectObject(memDC, memBmp);

//内存DC新在中心点

int newCentre = int(float(width)/2);

//开始旋转

for(int x = srcx1; x<=srcx2; x++)

for(int y = srcy1; y<=srcy2; y++)

{

COLORREF col = GetPixel(srcDC,x,y);

int newX = int((x-centreX)*sin(theta)+(y-centreY)*cos(theta));

int newY = int((x-centreX)*cos(theta)-(y-centreY)*sin(theta));

SetPixel(memDC , newX + newCentre, newY + newCentre, col);

}

//复制到目标DC上

BitBlt(destDC, destx1, desty1, width, height, memDC, 0,0,mode);

//释放内存

SelectObject(memDC, obmp);

DeleteDC(memDC);

DeleteObject(memBmp);

}

用法:

RotBlt(dc, 0,0,150,150,memDC,200,0, 45, SRCCOPY);

6. 如何将指定的窗体,以位图形式复制到系统剪切板上

void CScreenSnapDlg::toClipboard_Bio(CWnd * wnd, BOOL FullWnd)

{

CDC *dc;

if(FullWnd)

{ /* 抓取整个窗口 */

dc = new CWindowDC(wnd);

} /* 抓取整个窗口 */

else

{ /* 仅抓取客户区时 */

dc = new CClientDC(wnd);

} /* 仅抓取客户区时 */

CDC memDC;

memDC.CreateCompatibleDC(dc);

CBitmap bm;

CRect r;

if(FullWnd)

wnd->GetWindowRect(&r);

else

wnd->GetClientRect(&r);

CString s;

wnd->GetWindowText(s);

CSize sz(r.Width(), r.Height());

bm.CreateCompatibleBitmap(dc, sz.cx, sz.cy);

CBitmap * oldbm = memDC.SelectObject(&bm);

memDC.BitBlt(0, 0, sz.cx, sz.cy, dc, 0, 0, SRCCOPY);

//直接调用OpenClipboard(),而不用wnd->GetParent()->OpenClipboard();

wnd->OpenClipboard();

::EmptyClipboard();

::SetClipboardData(CF_BITMAP, bm.m_hObject);

CloseClipboard();

//恢复原始环境

memDC.SelectObject(oldbm);

bm.Detach();

delete dc;

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有