Мне удалось найти этот фрагмент кода и скомпилировать его с помощью Cairo:
#define LIBCAIRO_EXPORTS
#include <cairo/cairo.h>
#include <cairo/cairo-win32.h>
int main(int argc, char** argv)
{
cairo_surface_t *surface;
cairo_t *cr;
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 240, 80);
cr = cairo_create (surface);
cairo_select_font_face (cr, "serif", CAIRO_FONT_SLANT_NORMAL,
CAIRO_FONT_WEIGHT_BOLD);
cairo_set_font_size (cr, 32.0);
cairo_set_source_rgb (cr, 0.0, 0.0, 1.0);
cairo_move_to (cr, 10.0, 50.0);
cairo_show_text (cr, "Hello, World");
cairo_destroy (cr);
cairo_surface_write_to_png (surface, "hello.png");
cairo_surface_destroy (surface);
return 0;
}
Как видите, он создает изображение с текстом «Hello World» и сохраняет его на диске.
Как мне создать поверхность win32 и нарисовать вместо нее окно?
Я не могу использовать: cairo_win32_surface_create
Требуется hdc
и я не знаю что это. Я попытался прочитать несколько учебных пособий, но ни один из них не помог вам распечатать в новом окне.
Я нашел эту ссылку:
http://windrealm.org/cairo-gdi/
У него есть рабочая демонстрация, но она использует int WINAPI WinMain
, Я не хочу этим пользоваться.
Есть несколько способов получить дескриптор контекста устройства в Windows. Например, типично, что WM_PAINT
обработчик позвонит BeginPaint
чтобы получить контекст устройства, обновите содержимое окна и затем вызовите EndPaint
, В случаях, когда BeginPaint
а также EndPaint
не может использоваться (например, вне сообщения WM_PAINT), которое вы можете использовать GetDC
обновить окно и затем вызвать ReleaseDC
,
Контекст устройства, возвращаемый BeginPaint
а также GetDC
позволяют рисовать прямо в окне. Иногда, однако, вы хотите нарисовать прямо в растровое изображение. В этом случае вы бы позвонили CreateCompatibleDC
выберите растровое изображение, к которому хотите рисовать, сделайте свой рисунок и затем вызовите DeleteDC
,
В вашем случае вы ищете что-то вроде следующего:
HDC dc = GetDC(windowHandle);
cairo_win32_surface_create(dc);
ReleaseDC(windowHandle, dc);
Если вы не хотите создавать окно на этом этапе (поскольку вы просто сохраняете изображение), вы, вероятно, можете избежать использования окна рабочего стола для получения контекста устройства.
HWND windowHandle = GetDesktopWindow();
HDC dc = GetDC(windowHandle);
cairo_win32_surface_create(dc);
ReleaseDC(windowHandle, dc);
Существуют и другие вызовы, которые можно использовать для получения или создания контекста устройства. Вы можете найти список этих и связанных функций Вот
Создание и использование окна немного сложнее, поэтому я собираюсь предоставить вам основные шаги и пример кода, с которым вы можете поиграть. Чтобы создать и использовать окно …
RegisterClass
CreateWindow
или же CreateWindowEx
GetMessage
, TranslateMessage
а также DispatchMessage
Кроме того, вам нужно будет реализовать функцию для обработки сообщений окна, таких как WM_PAINT
,
ПРИМЕЧАНИЕ. Следующий код является НЕПРОВЕРЕННЫМ, но должно быть правильным.
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if(message == WM_PAINT)
{
HDC dc;
PAINTSTRUCT ps;
dc = BeginPaint(hwnd, &ps);
// do your drawing here
EndPaint(hwnd, &ps);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szClassName[] = TEXT("DrawSurfaceClass");
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
///////////////////////////////////////////////////////////
// Register a window "class"///////////////////////////////////////////////////////////
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)COLOR_WINDOW;
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szClassName;
if(!RegisterClass(&wndclass))
{
// error
return 1;
}
///////////////////////////////////////////////////////////
// Create the window and display it (if iCmdShow says so)
///////////////////////////////////////////////////////////
hwnd = CreateWindow(
szAppName,
TEXT("Draw Surface"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);///////////////////////////////////////////////////////////
// Run the message pump so the window proc recieves events
///////////////////////////////////////////////////////////
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
Я нашел самый простой способ для новичков открыть окно и нарисовать в нем несколько линий, это загрузить и настроить gtk + и использовать учебные пособия ZetCode.
Вам, вероятно, нужно скачать GTK отсюда:
http://gtk.hexchat.org/
Настройка Gtk +:
Использование GTK + в Visual C ++
Каирские уроки:
http://zetcode.com/gfx/cairo/
Не забудьте включить все DLL-файлы GTK в каталог, где находится ваш скомпилированный исполняемый файл.