6

このコード スニペットを見つけて 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. 私はそれを使いたくありません。

4

2 に答える 2

7

Windows でデバイス コンテキストへのハンドルを取得するには、いくつかの方法があります。たとえば、WM_PAINTハンドラーが を呼び出しBeginPaintてデバイス コンテキストを取得し、内容をウィンドウに更新してからを呼び出すのが一般的ですEndPaintBeginPaintEndPaintを使用できない場合 (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
  • を呼び出してメッセージ ポンプでメッセージを処理しGetMessageTranslateMessageDispatchMessage

さらに、 などのウィンドウ メッセージの処理を処理する関数を実装する必要があります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;
}
于 2013-04-16T21:26:16.483 に答える
2

初心者がウィンドウを開いて線を引く最も簡単な方法は、gtk+ をダウンロードしてセットアップし、ZetCode のチュートリアルを使用することです。

おそらくここから GTK をダウンロードする必要があります: http://gtk.hexchat.org/

Gtk+ のセットアップ: Visual C++ で GTK+ を使用する

カイロのチュートリアル: http://zetcode.com/gfx/cairo/

コンパイル済みの実行可能ファイルがあるディレクトリに、すべての GTK の dll ファイルを含めることを忘れないでください。

于 2013-04-17T18:47:53.760 に答える