Double Buffering
Bitmap을 생성하여 이를 활용한다.
class CustomControl : Control
{
private Bitmap DoubleBufferImage
{
get
{
if (bmDoubleBuffer == null)
{
bmDoubleBuffer = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);
}
return bmDoubleBuffer;
}
set
{
if (bmDoubleBuffer != null)
bmDoubleBuffer.Dispose();
bmDoubleBuffer = value;
}
}
protected override void OnResize(EventArgs e)
{
DoubleBufferImage = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);
base.OnResize(e);
}
// Override this method with no code to avoid flicker
protected override void OnPaintBackground(PaintEventArgs e) { }
protected override void OnPaint(PaintEventArgs e)
{
using (Graphics gOff = Graphics.FromImage(DoubleBufferImage))
{
gOff.Draw....
g.DrawImage(DoubleBufferImage, 0, 0);
}
}
ImageAttributes 의 제약 사항
DrawImage의 마지막 parameter로 넘겨주어 color-adjustment, grayscale, transparency, color-map table, color-threadhold등의 manipulation을 할 수 있도록 한다.
그러나, .NET Cf에서는 ImageAttributes.SetColorKey()를 통해서 transparency만 조절할 수 있다. 한 가지 색깔만 transparency로 설정할 수 있다.
Alphablend가 필요할 경우 Pinvoke를 사용해야 한다.
GradientFill이 필요할 경우 Pinvoke를 사용해야 한다.
회전된 Text 표시하기
LogFont 를 이용하여 Font에 효과를 주어 그림을 그릴 수 있다.
private Font CreateRotatedFont(string fontname, int angleInDegree)
{
LogFont logf = new LogFont();
using (Graphics g = this.CreateGraphics())
{
logf.Height = (int)(-18f * g.DpiY / curDPI);
logf.Escapement = angleInDegree * 10;
logf.Orientation = logf.Escapement;
logf.FaceName = fontname;
logf.CharSet = LogFontCharSet.Default;
logf.OutPrecision = LogFontPrecision.Default;
logf.ClipPrecision = LogFontClipPrecision.Default;
logf.Quality = LogFontQuality.ClearType;
logf.PitchAndFamily = LogFontPitchAndFamily.Default;
}
return Font.FromLogFont(logf);
}
Bitmap 데이터를 직접 건드리려는 경우에는 LockBits를 사용한다.
이 때 bitmap data의 pointer는 unmanaged pointer이므로 Marshal.Copy를 사용한다.
private void MakeMoreBlue(Bitmap bmp)
{
PixelFormat pxf = PixelFormat.Format24bppRgb;
// Lock the bitmap's bits
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, pxf);
IntPtr ptr = bmpData.Scan0;
int numBytes = bmpData.Stride * bmp.Height;
byte[] rgbValues = new byte[numBytes];
Marshal.Copy(ptr, rgbValues, 0, numBytes);
for (int counter = 0; counter < rgbValues.Length; counter += 6)
{
rgbValues[counter] = 255;
}
Marshal.Copy(rgbValues, 0, ptr, numBytes);
bmp.UnlockBits(bmpData);
}
2009년 1월 11일 일요일
2009년 1월 10일 토요일
.NET CF Version Check 하기와 P/Invoke 예제
To check the version of the installed .NET framework on the device.
\Windows\cgacutil
P/Invoke 사용하여 System API접근하기
.NET library에는 Platform 정보를 읽어올 수가 없다. 2.0에서
P/Invoke를 써야 한다.
[DllImport("coredll.dll")]
private static extern bool SystemParametersInfo(uint uiAction, uint uiParam, StringBuilder pvParam, uint fWinIni);
StringBuilder strbuild = new StringBuilder(200);
SystemParametersInfo(SPI_GETPLATFORMTYPE, 200, strbuild, 0);
* Kernel IO Control을 사용하여 device의 lowlevel을 access해야 하는 경우는 다음과 같이 P/Invoke를 사용한다.
[DllImport("coredll.dll", SetLastError = true)]
private static extern bool KernelIoControl(Int32 dwIoControlCode,
IntPtr lpInBuf, Int32 nInBufSize, byte[] lpOutBuf,
KernelIoControl(IOCTL_HAL_GET_DEVICEID, IntPtr.Zero, 0, outbuff, nBuffSize, ref dwOutBytes);
int error = Marshal.GetLastWin32Error();
LPVOID의 경우 return값을 받으려면 byte[] array를 사용하고 값을
넣을때는 BitConverter.GetBytes(value).CopyTo(array, index) 를
읽어온 데이터는 BitConverter.ToInt32(array, index) 를 사용한다. (Int32대신 각각에 해당하는 type을 넣는다)
* System 시간을 읽어오려면 GetSystemTime을 P/Invoke해야 한다
[DllImport("coredll.dll")]
private extern static void GetSystemTime(ref SYSTEMTIME lpSystemTime);
[DllImport("coredll.dll")]
private extern static uint SetSystemTime(ref SYSTEMTIME lpSystemTime);
[DllImport("coredll.dll")]
private extern static void GetLocalTime(ref SYSTEMTIME lpLocalTime);
private struct SYSTEMTIME
{
public ushort wYear;
public ushort wMonth;
public ushort wDayOfWeek;
public ushort wDay;
public ushort wHour;
public ushort wMinute;
public ushort wSecond;
public ushort wMilliseconds;
}
* Memory 정보 읽어오기
public struct MEMORYSTATUS
{
public UInt32 dwLength;
public UInt32 dwMemoryLoad;
public UInt32 dwTotalPhys;
public UInt32 dwAvailPhys;
public UInt32 dwTotalPageFile;
public UInt32 dwAvailPageFile;
public UInt32 dwTotalVirtual;
public UInt32 dwAvailVirtual;
}
[DllImport("CoreDll.dll")]
private static extern void GlobalMemoryStatus(ref MEMORYSTATUS lpBuffer);
[DllImport("CoreDll.dll")]
private static extern int GetSystemMemoryDivision
(
ref UInt32 lpdwStorePages,
ref UInt32 lpdwRamPages,
ref UInt32 lpdwPageSize
);
Getting the current directory
Windows Mobile 디바이스에는 current directory라는 개념이 없다.
따라서, path를 넘겨줘야 할 때는 반드시 fullpath를 만들어 주어야 하는데, 현재 실행되는 application의 폴더를 현재 폴더로 얻어오는 것이 일반적이다.
이를 얻어오는 방법은 Reflection을 사용한다.
String strAppDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase);
여기서 Path는 string을 인자로 받아 확장자, 파일 이름 등만을 파싱하는데 유용하게 쓰이는 helper class이다.
\Windows\cgacutil
P/Invoke 사용하여 System API접근하기
.NET library에는 Platform 정보를 읽어올 수가 없다. 2.0에서
P/Invoke를 써야 한다.
[DllImport("coredll.dll")]
private static extern bool SystemParametersInfo(uint uiAction, uint uiParam, StringBuilder pvParam, uint fWinIni);
StringBuilder strbuild = new StringBuilder(200);
SystemParametersInfo(SPI_GETPLATFORMTYPE, 200, strbuild, 0);
* Kernel IO Control을 사용하여 device의 lowlevel을 access해야 하는 경우는 다음과 같이 P/Invoke를 사용한다.
[DllImport("coredll.dll", SetLastError = true)]
private static extern bool KernelIoControl(Int32 dwIoControlCode,
IntPtr lpInBuf, Int32 nInBufSize, byte[] lpOutBuf,
KernelIoControl(IOCTL_HAL_GET_DEVICEID, IntPtr.Zero, 0, outbuff, nBuffSize, ref dwOutBytes);
int error = Marshal.GetLastWin32Error();
LPVOID의 경우 return값을 받으려면 byte[] array를 사용하고 값을
넣을때는 BitConverter.GetBytes(value).CopyTo(array, index) 를
읽어온 데이터는 BitConverter.ToInt32(array, index) 를 사용한다. (Int32대신 각각에 해당하는 type을 넣는다)
* System 시간을 읽어오려면 GetSystemTime을 P/Invoke해야 한다
[DllImport("coredll.dll")]
private extern static void GetSystemTime(ref SYSTEMTIME lpSystemTime);
[DllImport("coredll.dll")]
private extern static uint SetSystemTime(ref SYSTEMTIME lpSystemTime);
[DllImport("coredll.dll")]
private extern static void GetLocalTime(ref SYSTEMTIME lpLocalTime);
private struct SYSTEMTIME
{
public ushort wYear;
public ushort wMonth;
public ushort wDayOfWeek;
public ushort wDay;
public ushort wHour;
public ushort wMinute;
public ushort wSecond;
public ushort wMilliseconds;
}
* Memory 정보 읽어오기
public struct MEMORYSTATUS
{
public UInt32 dwLength;
public UInt32 dwMemoryLoad;
public UInt32 dwTotalPhys;
public UInt32 dwAvailPhys;
public UInt32 dwTotalPageFile;
public UInt32 dwAvailPageFile;
public UInt32 dwTotalVirtual;
public UInt32 dwAvailVirtual;
}
[DllImport("CoreDll.dll")]
private static extern void GlobalMemoryStatus(ref MEMORYSTATUS lpBuffer);
[DllImport("CoreDll.dll")]
private static extern int GetSystemMemoryDivision
(
ref UInt32 lpdwStorePages,
ref UInt32 lpdwRamPages,
ref UInt32 lpdwPageSize
);
Getting the current directory
Windows Mobile 디바이스에는 current directory라는 개념이 없다.
따라서, path를 넘겨줘야 할 때는 반드시 fullpath를 만들어 주어야 하는데, 현재 실행되는 application의 폴더를 현재 폴더로 얻어오는 것이 일반적이다.
이를 얻어오는 방법은 Reflection을 사용한다.
String strAppDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase);
여기서 Path는 string을 인자로 받아 확장자, 파일 이름 등만을 파싱하는데 유용하게 쓰이는 helper class이다.
피드 구독하기:
글 (Atom)