у меня так получилось................
#include <windows.h>
#include<math.h>
#define COUNT 1000
#define SAVE_AS 101
#define COLOR 201
#define RESET 301
#define ABOUT 401
HINSTANCE hInst;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void czCreateMenu(HWND);
void Save_As(HWND);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
static LPCWSTR szAppName = L"Graphics";
HWND hwnd;
MSG msg;
WNDCLASSEX wndclass;
wndclass.cbSize = sizeof(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;
wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
RegisterClassEx(&wndclass);
hwnd = CreateWindow(szAppName, L"Graphics", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
SetTimer(hwnd, 1, USER_TIMER_MINIMUM, NULL);
czCreateMenu(hwnd);
hInst = hInstance;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
int wmId;
static int cxClient, cyClient, Phase = 0;
HDC hdc;
PAINTSTRUCT ps;
CHOOSECOLOR cc;
static HPEN hPen;
static COLORREF color = RGB(0, 0, 0), acrCustClr[16];
unsigned i = 0;
const static int multiple = 100;
static POINT pt[COUNT * multiple] = { 0 };
static bool Move = true;
switch (iMsg)
{
case WM_CREATE:
for (double x = 0; x < COUNT; x += 0.05)
{
double y = 0;
pt[i].x = (LONG)(x / 5 * multiple);
double a = abs(sin(3 * x));
pt[i++].y = (LONG)(a * multiple);
}
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
switch (wmId)
{
case SAVE_AS:
Save_As(hwnd);
break;
case COLOR:
cc.lStructSize = sizeof(CHOOSECOLOR);
cc.hwndOwner = hwnd;
cc.lpCustColors = (LPDWORD)acrCustClr;
cc.rgbResult = color;
cc.Flags = CC_FULLOPEN | CC_RGBINIT;
ChooseColor(&cc);
color = cc.rgbResult;
InvalidateRect(hwnd, NULL, true);
break;
case RESET:
Phase = 0;
break;
case ABOUT:
MessageBox(hwnd, L"GraphicDrawer v.1.0\n© Pashkevich E.A., 2016", L"About", MB_OK | MB_ICONWARNING);
break;
}
break;
case WM_SIZE:
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
break;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
hPen = CreatePen(0, 1, color);
SelectObject(hdc, hPen);
MoveToEx(hdc, pt[0].x, cyClient / 2 - pt[0].y, 0);
for (unsigned j = Phase; j < cxClient + Phase; j++)
LineTo(hdc, pt[j].x - Phase, cyClient / 2 - pt[j].y);
EndPaint(hwnd, &ps);
break;
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
Move = !Move;
break;
case WM_TIMER:
if (Move){
Phase++;
InvalidateRect(hwnd, NULL, true);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd, iMsg, wParam, lParam);
}
void czCreateMenu(HWND hwnd)
{
HMENU MainMenu = CreateMenu();
HMENU mFile = CreatePopupMenu();
HMENU mView = CreatePopupMenu();
AppendMenu(MainMenu, MF_STRING | MF_POPUP, (UINT)mFile, L"&File");
{
AppendMenu(mFile, MF_STRING, SAVE_AS, L"Save as...");
}
AppendMenu(MainMenu, MF_STRING | MF_POPUP, (UINT)mView, L"&View");
{
AppendMenu(mView, MF_STRING, COLOR, L"Color");
}
AppendMenu(MainMenu, MF_STRING, RESET, L"Reset");
AppendMenu(MainMenu, MF_STRING, ABOUT, L"About");
SetMenu(hwnd, MainMenu);
}
void Save_As(HWND hwnd)
{
OPENFILENAME SaveDialog;
HANDLE SaveFile;
DWORD Written;
HDC hdcMem, hdcWindow;
HBITMAP hBitmap;
BYTE *ArrOfImg;
RECT rt;
int width = 0, height = 0;
ZeroMemory(&SaveDialog, sizeof(OPENFILENAME));
SaveDialog.lStructSize = sizeof(OPENFILENAME);
SaveDialog.hInstance = hInst;
SaveDialog.Flags = OFN_OVERWRITEPROMPT;
SaveDialog.lpstrFilter = L"*.bmp\0*.bmp\0\0";
SaveDialog.lpstrFile = new TCHAR[100];
SaveDialog.nMaxFile = _MAX_PATH;
memset(SaveDialog.lpstrFile, 0, 100);
GetSaveFileName(&SaveDialog);
if (!SaveDialog.lpstrFile[0]) return;
SaveFile = CreateFile(SaveDialog.lpstrFile, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
hdcWindow = GetDC(hwnd);
hdcMem = CreateCompatibleDC(hdcWindow);
GetClientRect(hwnd, &rt);
hBitmap = CreateCompatibleBitmap(hdcWindow, width = rt.right - rt.left, height = rt.bottom - rt.top);
SelectObject(hdcMem, hBitmap);
BitBlt(hdcMem, 0, 0, width, height, hdcWindow, 0, 0, SRCCOPY);
BITMAPINFO bmi;
memset(bmi.bmiColors, 0, sizeof(bmi.bmiColors));
bmi.bmiHeader.biBitCount = 24;
bmi.bmiHeader.biClrImportant = 0;
bmi.bmiHeader.biClrUsed = 0;
bmi.bmiHeader.biCompression = 0;
bmi.bmiHeader.biHeight = height;
bmi.bmiHeader.biWidth = width;
bmi.bmiHeader.biSizeImage = (width * 3 + width % 4) * height;
bmi.bmiHeader.biSize = 40;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biXPelsPerMeter = 0;
bmi.bmiHeader.biYPelsPerMeter = 0;
BITMAPFILEHEADER bmfh;
bmfh.bfType = MAKEWORD('B', 'M');
bmfh.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
bmfh.bfSize = bmfh.bfOffBits + bmi.bmiHeader.biSizeImage;
bmfh.bfReserved1 = 0;
bmfh.bfReserved2 = 0;
WriteFile(SaveFile, &bmfh, sizeof(BITMAPFILEHEADER), &Written, 0);
WriteFile(SaveFile, &bmi.bmiHeader, sizeof(BITMAPINFOHEADER), &Written, 0);
ArrOfImg = new BYTE[bmi.bmiHeader.biSizeImage];
GetDIBits(hdcMem, hBitmap, 0, bmi.bmiHeader.biHeight, ArrOfImg, &bmi, DIB_RGB_COLORS);
WriteFile(SaveFile, ArrOfImg, bmi.bmiHeader.biSizeImage, &Written, 0);
CloseHandle(SaveFile);
delete[] ArrOfImg;
}
Можно использовать GDI Plus, так себе подход, но зато проверенный временем:
Graphics graphics(hdc);
Pen pen(Color(255, 0, 0, 255));
graphics.DrawLine(&pen, 0, 0, 200, 100);
Пример от Microsoft (думаю, не сто́ит переносить сюда весь код).
Перевод документов на английский язык: Важность и ключевые аспекты
Какие существуют виды рекламных бордов и как выбрать подходящий?
Можно ли в C++ объявить несколько переменных и сразу присвоить одинаковое значение? Пример:
Здравствуйте! У меня проблема с функцией для вывода объекта в SDL
Имеется DOM дерево, нужен рендер на OpenGl,в QtТак как, у HTML нет координат, а OpenGL рисует по координатам, не понимаю как это сделать, по смещениям атрибутов...