用vc画图为了让x坐标上各数值的位置右对齐用TextOut使用了GetTextExtent函数来获得坐标值的字符串长度。当把图复制到剪贴板时相当于在剪贴板里画这个函数返回的坐标字符串长度就不正确。怎么实现上面要求的右对齐的功能给出完整的VC++代码
以下是一个实现在x坐标上右对齐的VC++代码示例:
#include <windows.h>
#include <tchar.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
TCHAR szAppName[] = _T("RightAlign");
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
if (!RegisterClass(&wndclass))
{
MessageBox(NULL, _T("This program requires Windows NT!"), szAppName, MB_ICONERROR);
return 0;
}
hwnd = CreateWindow(szAppName, _T("Right Align"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static int cxClient, cyClient;
static int cxChar, cyChar;
static TCHAR szText[256];
static int xValues[] = { 0, 50, 100, 150, 200, 250 };
static int yValues[] = { 100, 75, 125, 100, 50, 150 };
static int nValues = sizeof(xValues) / sizeof(int);
switch (message)
{
case WM_CREATE:
{
HDC hdc = GetDC(hwnd);
TEXTMETRIC tm;
GetTextMetrics(hdc, &tm);
cxChar = tm.tmAveCharWidth;
cyChar = tm.tmHeight;
ReleaseDC(hwnd, hdc);
}
return 0;
case WM_SIZE:
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
int i;
SIZE size;
SelectObject(hdc, GetStockObject(BLACK_PEN));
MoveToEx(hdc, 0, cyClient / 2, NULL);
LineTo(hdc, cxClient, cyClient / 2);
MoveToEx(hdc, cxClient / 2, 0, NULL);
LineTo(hdc, cxClient / 2, cyClient);
for (i = 0; i < nValues; i++)
{
wsprintf(szText, _T("%d"), xValues[i]);
GetTextExtentPoint32(hdc, szText, _tcslen(szText), &size);
TextOut(hdc, cxClient / 2 + xValues[i] - size.cx / 2, cyClient / 2 + cyChar, szText, _tcslen(szText));
Ellipse(hdc, cxClient / 2 + xValues[i] - cxChar, cyClient / 2 - yValues[i] - cyChar, cxClient / 2 + xValues[i] + cxChar, cyClient / 2 - yValues[i] + cyChar);
}
EndPaint(hwnd, &ps);
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
在这个示例中,我们使用GetTextExtentPoint32函数获取坐标值字符串的长度,并在x坐标上对齐。在WM_PAINT消息处理程序中,我们使用TextOut函数将字符串绘制在x坐标上。注意,我们使用_tcslen函数获取字符串的长度,而不是strlen。这是因为GetTextExtentPoint32函数需要一个TCHAR类型的字符串,而不是一个char类型的字符串。
要复制图像到剪贴板,我们可以添加一个WM_COMMAND消息处理程序,在其中使用OpenClipboard、EmptyClipboard、SetClipboardData和CloseClipboard函数。以下是示例代码:
case WM_COMMAND:
switch (LOWORD(wParam))
{
case ID_EDIT_COPY:
{
HDC hdcScreen, hdcMem;
HBITMAP hbmMem;
BITMAP bmp;
int cx, cy;
hdcScreen = GetDC(NULL);
cx = GetSystemMetrics(SM_CXSCREEN);
cy = GetSystemMetrics(SM_CYSCREEN);
hdcMem = CreateCompatibleDC(hdcScreen);
hbmMem = CreateCompatibleBitmap(hdcScreen, cx, cy);
SelectObject(hdcMem, hbmMem);
BitBlt(hdcMem, 0, 0, cx, cy, hdcScreen, 0, 0, SRCCOPY);
OpenClipboard(hwnd);
EmptyClipboard();
SetClipboardData(CF_BITMAP, hbmMem);
CloseClipboard();
DeleteDC(hdcMem);
ReleaseDC(NULL, hdcScreen);
}
return 0;
在这个示例中,我们首先获取屏幕的设备上下文和屏幕的大小。然后,我们创建一个与屏幕设备上下文兼容的内存设备上下文,并创建一个与屏幕大小相同的位图。我们将内存设备上下文和位图关联起来,并使用BitBlt函数将屏幕图像复制到内存设备上下文中。
接下来,我们打开剪贴板,清空剪贴板,并将位图设置为剪贴板数据。最后,我们删除内存设备上下文和释放屏幕设备上下文。
要使用此代码,您需要在窗口菜单中添加一个“复制”命令,如下所示:
case WM_CREATE:
{
HMENU hMenu = CreateMenu();
HMENU hSubMenu = CreatePopupMenu();
AppendMenu(hSubMenu, MF_STRING, ID_EDIT_COPY, _T("&Copy"));
AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, _T("&Edit"));
SetMenu(hwnd, hMenu);
}
return 0;
``
原文地址: http://www.cveoy.top/t/topic/epIc 著作权归作者所有。请勿转载和采集!