ゆく年くる年2009年01月12日 13:51

年賀状スタイルです。
今年は、丑年なので、牛をあしらって
もらいました。

C# レガシーウインドー2009年01月12日 10:50

あけまして、おめでとうございます。
本年もよろしくお願いします。

C# GDI+上で、GDIを再現してみました。
その意味で、レガシーウインドーです。
VC++のWindowsAPIを使っています。

C#にも線描のAPIがあるのに、なぜかといいますと
線描の軌跡を保存することが
非常にむずかしいからです。

で、線がすぐに消えるので、
ラインアートを実現するには、レガシー
ウインドーが実現できれば、OKかなというのが
動機です。

クラスでサポートできれば、
それほどむずかしくないと思います。
APIは、VC++のAPIを参照すれば
解決してゆくとおもいます。

タイマーを使った、OnPaintで
ダブルバッファ指定はなしです。
.
/*---------------------------------*/
/* カラーペン作成 */
/*---------------------------------*/

pen = Win32GDI.CreatePen(
Win32GDI.PenStyle.PS_SOLID, penWidth, (uint)ColorTranslator.ToWin32(col));

IntPtr oldpen = Win32GDI.SelectObject(hMemDC, pen);



/*---------------------------------*/
/* 線描 始点->終点   */
/*---------------------------------*/
if (freeline == 1)
{
Win32GDI.MoveToEx(hMemDC, sx, sy, IntPtr.Zero);

Win32GDI.LineTo(hMemDC, ex, ey);
sx = ex;
sy = ey;

}

参考クラス

class Win32GDI
{
public enum PenStyle
{

PS_SOLID = 0 //実線
など

};

public enum BrushStyles
{
BS_SOLID = 0,
BS_NULL = 1,
BS_HATCHED = 2,
BS_PATTERN = 3,
など
}

public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;

public void rect(int left,int top,int right,int bottom)
{
this.left = left;
this.right = right;
this.top = top;
this.bottom = bottom;

}

}


// 透明、不透明
public const int TRANSPARENT = 1;
public const int OPAQUE = 2;

// Constants used by uFormat argument of DrawText call
private const int DT_TOP = 0x00000000;
private const int DT_LEFT = 0x00000000;
private const int DT_CENTER = 0x00000001;
private const int DT_RIGHT = 0x00000002;
private const int DT_VCENTER = 0x00000004;
private const int DT_BOTTOM = 0x00000008;
private const int DT_WORDBREAK = 0x00000010;


public const int PATCOPY = 0xF00021;

public const int SRCCOPY = 13369376;

[DllImport("gdi32.dll", EntryPoint = "DeleteDC")]
public static extern IntPtr DeleteDC(IntPtr hDc);

[DllImport("gdi32.dll", EntryPoint = "DeleteObject")]
public static extern IntPtr DeleteObject(IntPtr hDc);

[DllImport("gdi32.dll", EntryPoint = "BitBlt")]
public static extern bool BitBlt(IntPtr hsrcDest, int xDest,
int yDest, int wDest, int hsrcDest, IntPtr hdcSource,
int xSrc, int ySrc, int ROp);

[DllImport("gdi32.dll", EntryPoint = "CreateCompatibleBitmap")]
public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc,
int nWidth, int nHeight);

[DllImport("gdi32.dll", EntryPoint = "CreateCompatibleDC")]
public static extern IntPtr CreateCompatibleDC(IntPtr hdc);

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


[DllImport("gdi32.dll", EntryPoint = "TextOut")]
public static extern bool TextOut(IntPtr hdcDest, int x, int y, string moji, int nagasa);

[DllImport("gdi32.dll", EntryPoint = "LineTo")]
public static extern bool LineTo(IntPtr hDC, int x, int y);

[DllImport("gdi32.dll", EntryPoint = "MoveToEx")]
public static extern bool MoveToEx(IntPtr hDC, int x, int y, IntPtr OldPoint);

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

[DllImportAttribute("gdi32.dll", EntryPoint = "CreateSolidBrush")]
//public static extern IntPtr CreateSolidBrush(BrushStyles enBrushStyle, int crColor);
public static extern IntPtr CreateSolidBrush(int crColor);

[DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true,
EntryPoint = "PatBlt")]
public static extern bool PatBlt(IntPtr hdc, int left, int top, int width, int height, int rop);

[DllImport("gdi32.dll")]
public static extern int SetBkMode(IntPtr hdc, int iBkMode);

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

[DllImport("user32.dll")]
public static extern int DrawText(IntPtr hdc, string lpString, int nCount,
ref RECT lpRect, uint uFormat);

[DllImport("gdi32")]
public static extern bool Ellipse(IntPtr hdc, int nLeft, int nTop, int nRight, int nBottom);

2008年 クリスマスです2009年01月12日 10:27

遅くなりましたが、
2008年度版クリスマスカードです

レガシーウインドーを使っています
一応、C#上でWindwos API
を使っています

Win32GDI.MoveToEx(hMemDC, sx, sy, IntPtr.Zero);

Win32GDI.LineTo(hMemDC, ex, ey);

線描によるラインアートの
改良点描です

GP21 2ボールで追加2007年10月30日 19:54

C#には、XNAのように便利なベクトルクラスがないので
今回特別に2D版のVector2クラスを開発しましたので
実装してください。oh13からDownLoadしてください。
なお、メンバー変数はpublicにしてあります。


また、VC++のAPI関数GetClientRect(hWnd、&rect)を
Musicクラスに追加実装しましたので、新しくDownLoad
して、上書きして実装してください。

class Vector2
{

public float x, y;

// コンストラクタ

public Vector2()
{

}

public Vector2(float x, float y)
{
this.x = x;
this.y = y;

}


/*-------------------------------------*/
/* ベクトル 加算 */
/*-------------------------------------*/
public static Vector2 operator +(Vector2 v1, Vector2 v2)
{

return
(
new Vector2(v1.x + v2.x, v1.y + v2.y)
);
}

/*-------------------------------------*/
/* ベクトル 減算 */
/*-------------------------------------*/
public static Vector2 operator -(Vector2 v1, Vector2 v2)
{

return
(
new Vector2(v1.x - v2.x, v1.y - v2.y)
);
}

/*-------------------------------------*/
/* ベクトルの向き 反対にする */
/*-------------------------------------*/
public static Vector2 operator -(Vector2 v1)
{
return (
new Vector2(-v1.x, -v1.y)
);
}

/*-------------------------------------*/
/* ベクトル 長さ abs */
/*-------------------------------------*/
public float abs()
{
return (float)Math.Sqrt(x * x + y * y);
}

/*-------------------------------------*/
/* ベクトル 内積     */
/*-------------------------------------*/
public static float DotProduct(Vector2 v1, Vector2 v2)
{
return (v1.x * v2.x + v1.y * v2.y);
}

/*-------------------------------------*/
/* ベクトル v1 長さ */
/*-------------------------------------*/
public float Magnitude(Vector2 v1)
{
return (float)Math.Sqrt(v1.x * v1.x + v1.y * v1.y);
}

/*-------------------------------------*/
/* ベクトル スカラー倍 */
/*-------------------------------------*/
public static Vector2 operator *(Vector2 v1, float s)
{

return (new Vector2(v1.x * s, v1.y * s));
}

/*-------------------------------------*/
/* ベクトル スカラー割り */
/*-------------------------------------*/
public static Vector2 operator /(Vector2 v1, float s)
{
if (s == 0)
{
throw new DivideByZeroException("ゼロ割だよ");
}
return (new Vector2(v1.x / s, v1.y / s));
}

/*-------------------------------------*/
/* ベクトル v1 単位ベクトル 長さ1 */
/*-------------------------------------*/
public static Vector2 Normalize(Vector2 v1)
{
float mag = (float)Math.Sqrt(v1.x * v1.x + v1.y * v1.y);


if (mag != 0)
{
return
(
new Vector2(v1.x / mag, v1.y / mag)
);
}
else
{
return
(
new Vector2(v1.x, v1.y)
);
//throw new DivideByZeroException("ゼロ割だよ");
}
}
}

クライアント領域取得API関数


[DllImport("user32.dll")]//2007-09-25
public static extern bool GetClientRect(IntPtr hWnd, [In, Out] ref Rectangle lpRect);