情報アイランド

「情報を制する者は世界を制す」をモットーに様々な情報を提供することを目指すブログです。現在はプログラミング関連情報が多めですが、投資関連情報も取り扱っていきたいです。

C#でWIN32API step10 図形描画

step8:ここまでのまとめ(その1)

step9:FPSを測定する

今回は幾つかの図形を描画してみます。

段々とプログラムが長くなり見にくいものになってきたので、今回からメッセージの処理方法を少々変更しました。

以下のように、ウィンドウプロシージャの本体では辞書型に登録されたメッセージ処理プロシージャのリストを走査するだけにし、具体的な処理はそのメッセージ処理プロシージャを呼び出すことによって行う方式に変更しました。

public static Dictionary<uint, WIN32.Window.WNDPROC> mainwndprocs = new Dictionary<uint, WIN32.Window.WNDPROC>()
{
    { WIN32.Window.WM_CREATE, WM_CREATE },
    { WIN32.Window.WM_DESTROY, WM_DESTROY },
    { WIN32.Window.WM_PAINT, WM_PAINT },
};

private static IntPtr WndProc(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam)
{
    foreach (var proc in mainwndprocs)
        if (proc.Key == uMsg)
            return proc.Value(hWnd, uMsg, wParam, lParam);

    return WIN32.Window.DefWindowProc(hWnd, uMsg, wParam, lParam);
}

WM_PAINTメッセージの処理を追加します。

単に適当なAPIを呼び出すだけなので難しい点はないです。作成したリソースを削除しなければならないことには注意してください。

private static IntPtr WM_PAINT(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam)
{
    WIN32.Draw.PAINTSTRUCT paintstruct;

    IntPtr hdc = WIN32.Draw.BeginPaint(hWnd, out paintstruct);

    WIN32.Draw.SelectObject(hdc, WIN32.Draw.GetStockObject(WIN32.Draw.WHITE_BRUSH));
    WIN32.Draw.SetPixel(hdc, 100, 100, 0x000000FF);
    WIN32.Draw.SetPixelV(hdc, 100, 200, 0x000000FF);

    IntPtr hpen = WIN32.Draw.CreatePen(WIN32.Draw.PS.PS_DASH, 1, 0x00FF0000);
    WIN32.Draw.SelectObject(hdc, hpen);
    WIN32.Window.POINT point = new WIN32.Window.POINT();
    WIN32.Draw.MoveToEx(hdc, 10, 10, ref point);
    WIN32.Draw.LineTo(hdc, 222, 123);
    WIN32.Draw.DeleteObject(hpen);

    WIN32.Draw.SelectObject(hdc, WIN32.Draw.GetStockObject(WIN32.Draw.BLACK_PEN));
    IntPtr hsolidbrush = WIN32.Draw.CreateSolidBrush(0x0000FF00);
    WIN32.Draw.SelectObject(hdc, hsolidbrush);
    WIN32.Draw.Rectangle(hdc, 25, 25, 75, 75);
    WIN32.Draw.Ellipse(hdc, 25, 80, 150, 150);
    WIN32.Draw.DeleteObject(hsolidbrush);
    IntPtr hhatchbrush = WIN32.Draw.CreateHatchBrush(WIN32.Draw.HS.HS_CROSS, 0x000000FF);
    WIN32.Draw.SelectObject(hdc, hhatchbrush);
    WIN32.Draw.RoundRect(hdc, 25, 160, 75, 250, 5, 10);
    WIN32.Draw.Polygon(hdc, new WIN32.Window.POINT[] { new WIN32.Window.POINT() { x = 100, y = 100 }, new WIN32.Window.POINT() { x = 150, y = 200 }, new WIN32.Window.POINT() { x = 50, y = 200 }, }, 3);
    WIN32.Draw.DeleteObject(hhatchbrush);

    WIN32.Draw.EndPaint(hWnd, ref paintstruct);

    return IntPtr.Zero;
}

こちらが、P/I用のコードです(前回からの追加部分)。

using System;
using System.Runtime.InteropServices;

namespace Anttn.WIN32
{
    public static partial class Window
    {
    (省略)

        public const uint WM_PAINT = 0x000F;

    (省略)
    }
}
using System;
using System.Runtime.InteropServices;

namespace Anttn.WIN32
{
    public static partial class Draw
    {
        [DllImport("user32.dll")]
        public static extern IntPtr BeginPaint(IntPtr hWnd, out PAINTSTRUCT lpPaint);

        [DllImport("user32.dll")]
        public static extern bool EndPaint(IntPtr hWnd, [In] ref PAINTSTRUCT lpPaint);

        [DllImport("gdi32.dll")]
        public static extern uint SetPixel(IntPtr hdc, int X, int Y, uint crColor);

        [DllImport("gdi32.dll")]
        public static extern bool SetPixelV(IntPtr hdc, int X, int Y, uint crColor);

        [DllImport("gdi32.dll")]
        public static extern bool MoveToEx(IntPtr hdc, int X, int Y, [In] ref WIN32.Window.POINT lpPoint);

        [DllImport("gdi32.dll")]
        public static extern bool LineTo(IntPtr hdc, int nXEnd, int nYEnd);

        [DllImport("gdi32.dll")]
        public static extern bool Rectangle(IntPtr hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);

        [DllImport("gdi32.dll")]
        public static extern bool Ellipse(IntPtr hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);

        [DllImport("gdi32.dll")]
        public static extern bool RoundRect(IntPtr hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect, int nWidth, int nHeight);

        [DllImport("gdi32.dll")]
        public static extern bool Polygon(IntPtr hdc, WIN32.Window.POINT[] lpPoints, int nCount);

        [DllImport("gdi32.dll")]
        public static extern IntPtr GetStockObject(int fnObject);

        [DllImport("gdi32.dll")]
        public static extern IntPtr CreatePen(PS fnPenStyle, int nWidth, uint crColor);

        [DllImport("gdi32.dll")]
        public static extern IntPtr CreateSolidBrush(uint crColor);

        [DllImport("gdi32.dll")]
        public static extern IntPtr CreateHatchBrush(HS fnStyle, uint clrref);

        [DllImport("gdi32.dll")]
        public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);

        [DllImport("gdi32.dll")]
        public static extern bool DeleteObject(IntPtr hObject);

        [StructLayout(LayoutKind.Sequential)]
        public struct PAINTSTRUCT
        {
            public IntPtr hdc;
            public bool fErase;
            public WIN32.Window.RECT rcPaint;
            public bool fRestore;
            public bool fIncUpdate;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
            public byte[] rgbReserved;
        }

        public enum PS : int
        {
            PS_SOLID = 0x00000000,
            PS_DASH = 0x00000001,
            PS_DOT = 0x00000002,
            PS_DASHDOT = 0x00000003,
            PS_DASHDOTDOT = 0x00000004,
            PS_NULL = 0x00000005,
            PS_INSIDEFRAME = 0x00000006,
            PS_USERSTYLE = 0x00000007,
            PS_ALTERNATE = 0x00000008,
            PS_ENDCAP_ROUND = 0x00000000,
            PS_ENDCAP_SQUARE = 0x00000100,
            PS_ENDCAP_FLAT = 0x00000200,
            PS_JOIN_ROUND = 0x00000000,
            PS_JOIN_BEVEL = 0x00001000,
            PS_JOIN_MITER = 0x00002000,
            PS_COSMETIC = 0x00000000,
            PS_GEOMETRIC = 0x00010000,
        };

        public enum HS : int
        {
            HS_HORIZONTAL = 0x00000000,
            HS_VERTICAL = 0x00000001,
            HS_FDIAGONAL = 0x00000002,
            HS_BDIAGONAL = 0x00000003,
            HS_CROSS = 0x00000004,
            HS_DIAGCROSS = 0x00000005
        }

        public const int WHITE_BRUSH = 0;
        public const int LTGRAY_BRUSH = 1;
        public const int GRAY_BRUSH = 2;
        public const int DKGRAY_BRUSH = 3;
        public const int BLACK_BRUSH = 4;
        public const int NULL_BRUSH = 5;
        public const int HOLLOW_BRUSH = NULL_BRUSH;
        public const int WHITE_PEN = 6;
        public const int BLACK_PEN = 7;
        public const int NULL_PEN = 8;
        public const int OEM_FIXED_FONT = 10;
        public const int ANSI_FIXED_FONT = 11;
        public const int ANSI_VAR_FONT = 12;
        public const int SYSTEM_FONT = 13;
        public const int DEVICE_DEFAULT_FONT = 14;
        public const int DEFAULT_PALETTE = 15;
        public const int SYSTEM_FIXED_FONT = 16;
        public const int DEFAULT_GUI_FONT = 17;
        public const int DC_BRUSH = 18;
        public const int DC_PEN = 19;
    }
}

下のように描画されます。

この程度の描画処理ではFPSは殆ど変化しません。

pizyumi
プログラミング歴19年のベテランプログラマー。業務システム全般何でも作れます。現在はWeb系の技術を勉強中。
スポンサーリンク

-C#, WIN32API