用vc画图为了让x坐标上各数值的位置右对齐用TextOut使用了GetTextExtent函数来获得坐标值的字符串长度。当把图复制到剪贴板时相当于在剪贴板里画这个函数返回的坐标字符串长度就不正确。请提供正确的代码如果不适用drawtext时
,可以尝试使用ExtTextOut函数。
以下是一个示例代码:
// 获取字符串宽度
int GetTextWidth(HDC hdc, LPCTSTR lpStr)
{
SIZE size = { 0 };
GetTextExtentPoint32(hdc, lpStr, lstrlen(lpStr), &size);
return size.cx;
}
// 绘制坐标轴刻度值
void DrawScaleValues(HDC hdc, int left, int top, int right, int bottom, int xInterval, int yInterval)
{
// 绘制 x 轴刻度值
for (int x = left; x <= right; x += xInterval)
{
TCHAR szValue[16] = { 0 };
_stprintf_s(szValue, _T("%d"), x);
int cx = GetTextWidth(hdc, szValue);
ExtTextOut(hdc, x - cx / 2, bottom + 5, ETO_CLIPPED | ETO_OPAQUE, nullptr, szValue, lstrlen(szValue), nullptr);
}
// 绘制 y 轴刻度值
for (int y = top; y <= bottom; y += yInterval)
{
TCHAR szValue[16] = { 0 };
_stprintf_s(szValue, _T("%d"), y);
int cx = GetTextWidth(hdc, szValue);
ExtTextOut(hdc, left - cx - 5, y - 8, ETO_CLIPPED | ETO_OPAQUE, nullptr, szValue, lstrlen(szValue), nullptr);
}
}
// 绘制坐标轴
void DrawAxis(HDC hdc, int left, int top, int right, int bottom)
{
// x 轴
MoveToEx(hdc, left, bottom, nullptr);
LineTo(hdc, right, bottom);
// y 轴
MoveToEx(hdc, left, top, nullptr);
LineTo(hdc, left, bottom);
}
// 绘制图形
void DrawGraph(HDC hdc, int left, int top, int right, int bottom)
{
// TODO: 绘制图形
}
// 绘制函数
void OnPaint(HWND hWnd)
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
// 获取客户区大小
RECT rcClient;
GetClientRect(hWnd, &rcClient);
// 绘制坐标轴
DrawAxis(hdc, 50, 50, rcClient.right - 50, rcClient.bottom - 50);
// 绘制坐标轴刻度值
DrawScaleValues(hdc, 50, 50, rcClient.right - 50, rcClient.bottom - 50, 50, 50);
// 绘制图形
DrawGraph(hdc, 50, 50, rcClient.right - 50, rcClient.bottom - 50);
EndPaint(hWnd, &ps);
}
// 复制图像到剪贴板
void CopyToClipboard(HWND hWnd)
{
// 获取客户区大小
RECT rcClient;
GetClientRect(hWnd, &rcClient);
// 创建兼容的内存设备上下文
HDC hdcMem = CreateCompatibleDC(nullptr);
HBITMAP hBitmap = CreateCompatibleBitmap(GetDC(hWnd), rcClient.right, rcClient.bottom);
SelectObject(hdcMem, hBitmap);
// 绘制图像到内存设备上下文
OnPaint(hWnd);
BitBlt(hdcMem, 0, 0, rcClient.right, rcClient.bottom, GetDC(hWnd), 0, 0, SRCCOPY);
// 将图像复制到剪贴板
OpenClipboard(hWnd);
EmptyClipboard();
SetClipboardData(CF_BITMAP, hBitmap);
CloseClipboard();
// 释放资源
DeleteObject(hBitmap);
DeleteDC(hdcMem);
}
// 窗口过程
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_PAINT:
OnPaint(hWnd);
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case ID_COPY:
CopyToClipboard(hWnd);
break;
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
在上述代码中,GetTextWidth函数用于获取字符串的宽度,DrawScaleValues函数用于绘制坐标轴刻度值,DrawAxis函数用于绘制坐标轴,DrawGraph函数用于绘制图形,OnPaint函数用于处理绘制消息,CopyToClipboard函数用于将图像复制到剪贴板。在绘制坐标轴刻度值时,使用了ExtTextOut函数代替TextOut函数,以便可以正确计算字符串的宽度
原文地址: http://www.cveoy.top/t/topic/eo9J 著作权归作者所有。请勿转载和采集!