ゆく年くる年 ― 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);
本年もよろしくお願いします。
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);
線描によるラインアートの
改良点描です
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);
今回特別に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);
最近のコメント