728x90
반응형
728x170
▶ MainForm.cs
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace TestProject
{
/// <summary>
/// 메인 폼
/// </summary>
public partial class MainForm : Form
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Import
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Private
#region 디바이스 컨텍스트 생성하기 - CreateDC(driverName, deviceName, port, initialDataHandle)
/// <summary>
/// 디바이스 컨텍스트 생성하기
/// </summary>
/// <param name="driverName">드라이버명</param>
/// <param name="deviceName">장치명</param>
/// <param name="port">포트</param>
/// <param name="initialDataHandle">초기 데이터 핸들</param>
/// <returns>디바이스 컨텍스트 핸들</returns>
[DllImport("gdi32")]
private static extern IntPtr CreateDC(string driverName, string deviceName, string port, IntPtr initialDataHandle);
#endregion
#region 디바이스 컨텍스트 삭제하기 - DeleteDC(deviceContextHandle)
/// <summary>
/// 디바이스 컨텍스트 삭제하기
/// </summary>
/// <param name="deviceContextHandle">디바이스 컨텍스트 핸들</param>
/// <returns>처리 결과</returns>
[DllImport("gdi32")]
private static extern bool DeleteDC(IntPtr deviceContextHandle);
#endregion
#region 클라이언트 좌표에서 화면 좌표 구하기 - ClientToScreen(windowHandle, screenPoint)
/// <summary>
/// 클라이언트 좌표에서 화면 좌표 구하기
/// </summary>
/// <param name="windowHandle">윈도우 핸들</param>
/// <param name="screenPoint">화면 좌표계 포인트</param>
/// <returns>처리 결과</returns>
[DllImport("user32")]
private static extern bool ClientToScreen(IntPtr windowHandle, ref Point screenPoint);
#endregion
#region 비트맵 복사하기 - BitBlt(targetDeviceContextHandle, targetX, targetY, width, height, sourceDeviceContextHandle, sourceX, sourceY, rasterOperationCode
/// <summary>
/// 비트맵 복사하기
/// </summary>
/// <param name="targetDeviceContextHandle">타겟 디바이스 컨텍스트 핸들</param>
/// <param name="targetX">타겟 X</param>
/// <param name="targetY">타겟 Y</param>
/// <param name="width">너비</param>
/// <param name="height">높이</param>
/// <param name="sourceDeviceContextHandle">소스 디바이스 컨텍스트 핸들</param>
/// <param name="sourceX">소스 X</param>
/// <param name="sourceY">소스 Y</param>
/// <param name="rasterOperationCode">래스터 연산 코드</param>
/// <returns>처리 결과</returns>
[DllImport("gdi32")]
private static extern bool BitBlt
(
IntPtr targetDeviceContextHandle,
int targetX,
int targetY,
int width,
int height,
IntPtr sourceDeviceContextHandle,
int sourceX,
int sourceY,
int rasterOperationCode
);
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// SRCCOPY
/// </summary>
private const int SRCCOPY = 0xcc0020;
/// <summary>
/// 드래그 문자열
/// </summary>
private string dragString;
/// <summary>
/// 드래그 문자열 포인트
/// </summary>
private Point dragStringPoint;
/// <summary>
/// 드래그 문자열 폰트
/// </summary>
private Font dragStringFont;
/// <summary>
/// 드래그 이미지 크기
/// </summary>
private Size dragImageSize;
/// <summary>
/// 마우스 DOWN 여부
/// </summary>
private bool mouseDown = false;
/// <summary>
/// 마우스 델타 포인트
/// </summary>
private Point mouseDeltaPoint;
/// <summary>
/// 전체 화면 디바이스 컨텍스트 핸들
/// </summary>
private IntPtr displayDeviceContextHandle;
/// <summary>
/// 전체 화면 그래픽스
/// </summary>
private Graphics displayGraphics;
/// <summary>
/// 백업 저장소 비트맵
/// </summary>
private Bitmap backingStoreBitmap;
/// <summary>
/// 백업 저장소 그래픽스
/// </summary>
private Graphics backingStoreGraphics;
/// <summary>
/// 백업 저장소 디바이스 컨텍스트 핸들
/// </summary>
private IntPtr backingStoreDeviceContextHandle;
/// <summary>
/// 백업 저장소 포인트
/// </summary>
private Point backingStorePoint;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - MainForm()
/// <summary>
/// 생성자
/// </summary>
public MainForm()
{
InitializeComponent();
this.dragString = "Drag Me!";
this.dragStringPoint = new Point(100, 100);
this.dragStringFont = new Font("Times New Roman", 14, FontStyle.Bold);
Load += Form_Load;
MouseDown += Form_MouseDown;
MouseMove += Form_MouseMove;
MouseUp += Form_MouseUp;
Paint += Form_Paint;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Private
//////////////////////////////////////////////////////////////////////////////// Event
#region 폼 로드시 처리하기 - Form_Load(sender, e)
/// <summary>
/// 폼 로드시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void Form_Load(object sender, EventArgs e)
{
Graphics graphics = CreateGraphics();
SizeF dragStringSize = graphics.MeasureString(this.dragString, this.dragStringFont);
this.dragImageSize = new Size((int)dragStringSize.Width, (int)dragStringSize.Height);
graphics.Dispose();
}
#endregion
#region 폼 마우스 DOWN 처리하기 - Form_MouseDown(sender, e)
/// <summary>
/// 폼 마우스 DOWN 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void Form_MouseDown(object sender, MouseEventArgs e)
{
Rectangle dragStringRectangle = new Rectangle
(
this.dragStringPoint,
new Size(this.dragImageSize.Width, this.dragImageSize.Height)
);
if(dragStringRectangle.Contains(e.Location))
{
this.mouseDown = true;
this.mouseDeltaPoint = new Point(e.X - this.dragStringPoint.X, e.Y - this.dragStringPoint.Y);
Point screenPoint = GetScreenPoint(e.X, e.Y);
screenPoint.X -= this.mouseDeltaPoint.X;
screenPoint.Y -= this.mouseDeltaPoint.Y;
SetDisplayGraphics();
this.backingStoreBitmap = new Bitmap(this.dragImageSize.Width, this.dragImageSize.Height);
this.backingStoreGraphics = Graphics.FromImage(backingStoreBitmap);
this.backingStoreDeviceContextHandle = this.backingStoreGraphics.GetHdc();
BitBlt
(
this.backingStoreDeviceContextHandle,
0,
0,
this.backingStoreBitmap.Width, this.backingStoreBitmap.Height,
this.displayDeviceContextHandle,
screenPoint.X,
screenPoint.Y,
SRCCOPY
);
this.backingStorePoint = new Point(screenPoint.X, screenPoint.Y);
DrawDragImage(this.displayGraphics, true, screenPoint.X, screenPoint.Y, dragString);
}
}
#endregion
#region 폼 마우스 이동시 처리하기 - Form_MouseMove(sender, e)
/// <summary>
/// 폼 마우스 이동시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void Form_MouseMove(object sender, MouseEventArgs e)
{
if(this.mouseDown)
{
Point screenPoint = GetScreenPoint(e.X, e.Y);
screenPoint.X -= this.mouseDeltaPoint.X;
screenPoint.Y -= this.mouseDeltaPoint.Y;
BitBlt
(
this.displayDeviceContextHandle,
this.backingStorePoint.X,
this.backingStorePoint.Y,
this.backingStoreBitmap.Width,
this.backingStoreBitmap.Height,
this.backingStoreDeviceContextHandle,
0,
0,
SRCCOPY
);
BitBlt
(
this.backingStoreDeviceContextHandle,
0,
0,
this.backingStoreBitmap.Width,
this.backingStoreBitmap.Height,
this.displayDeviceContextHandle,
screenPoint.X,
screenPoint.Y,
SRCCOPY
);
this.backingStorePoint = new Point(screenPoint.X, screenPoint.Y);
DrawDragImage(this.displayGraphics, true, screenPoint.X, screenPoint.Y, this.dragString);
}
}
#endregion
#region 폼 마우스 UP 처리하기 - Form_MouseUp(sender, e)
/// <summary>
/// 폼 마우스 UP 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void Form_MouseUp(object sender, MouseEventArgs e)
{
if(this.mouseDown)
{
this.mouseDown = false;
BitBlt
(
this.displayDeviceContextHandle,
this.backingStorePoint.X,
this.backingStorePoint.Y,
this.backingStoreBitmap.Width,
this.backingStoreBitmap.Height,
this.backingStoreDeviceContextHandle,
0,
0,
SRCCOPY
);
DisposeDisplayDeviceContext();
this.backingStoreGraphics.ReleaseHdc(this.backingStoreDeviceContextHandle);
this.backingStoreGraphics.Dispose();
this.backingStoreBitmap.Dispose();
this.backingStoreBitmap = null;
}
}
#endregion
#region 폼 페인트시 처리하기 - Form_Paint(sender, e)
/// <summary>
/// 폼 페인트시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void Form_Paint(object sender, PaintEventArgs e)
{
Graphics graphics = e.Graphics;
graphics.FillRectangle(Brushes.Bisque, ClientRectangle);
Font font = new Font("Times New Roman", 32);
graphics.DrawString("Hello, World!", font, Brushes.Blue, 10, 10);
font.Dispose();
DrawDragImage(graphics, false, this.dragStringPoint.X, this.dragStringPoint.X, this.dragString);
}
#endregion
//////////////////////////////////////////////////////////////////////////////// Function
#region 화면 포인트 구하기 - GetScreenPoint(x, y)
/// <summary>
/// 화면 포인트 구하기
/// </summary>
/// <param name="x">X</param>
/// <param name="y">Y</param>
/// <returns>화면 포인트</returns>
private Point GetScreenPoint(int x, int y)
{
Point screenPoint = new Point(x, y);
ClientToScreen(Handle, ref screenPoint);
return screenPoint;
}
#endregion
#region 전체 화면 그래픽스 설정하기 - SetDisplayGraphics()
/// <summary>
/// 전체 화면 그래픽스 설정하기
/// </summary>
private void SetDisplayGraphics()
{
this.displayDeviceContextHandle = CreateDC("DISPLAY", null, null, (IntPtr)null);
this.displayGraphics = Graphics.FromHdc(this.displayDeviceContextHandle);
}
#endregion
#region 드래그 이미지 그리기 - DrawDragImage(graphics, alphaBlending, x, y, text)
/// <summary>
/// 드래그 이미지 그리기
/// </summary>
/// <param name="graphics">그래픽스</param>
/// <param name="alphaBlending">알파 블렌딩 적용 여부</param>
/// <param name="x">X</param>
/// <param name="y">Y</param>
/// <param name="text">텍스트</param>
private void DrawDragImage(Graphics graphics, bool alphaBlending, int x, int y, string text)
{
Rectangle rectangle = new Rectangle(x, y, this.dragImageSize.Width, this.dragImageSize.Height);
if(alphaBlending)
{
Color color1 = Color.FromArgb(0 , Color.Red);
Color color2 = Color.FromArgb(80, Color.Red);
Rectangle rectangle1 = new Rectangle
(
rectangle.Left,
rectangle.Top,
rectangle.Width / 2,
rectangle.Height
);
Rectangle rectangle2 = new Rectangle
(
rectangle.Left + rectangle.Width / 2,
rectangle.Top,
rectangle.Width / 2,
rectangle.Height
);
LinearGradientBrush brush1 = new LinearGradientBrush(rectangle1, color1, color2, 0f);
LinearGradientBrush brush2 = new LinearGradientBrush(rectangle2, color2, color1, 0f);
graphics.FillRectangle
(
brush1,
new Rectangle
(
rectangle1.Left + 1,
rectangle1.Top,
rectangle1.Width + 1,
rectangle1.Height
)
);
graphics.FillRectangle(brush2, rectangle2);
brush1.Dispose();
brush2.Dispose();
}
else
{
graphics.FillRectangle(Brushes.Red, rectangle);
}
Color textColor;
if(alphaBlending)
{
textColor = Color.FromArgb(80, Color.Black);
}
else
{
textColor = Color.Black;
}
Brush textBrush = new SolidBrush(textColor);
graphics.DrawString(text, this.dragStringFont, textBrush, rectangle);
textBrush.Dispose();
}
#endregion
#region 전체 화면 디바이스 컨텍스트 리소스 해제하기 - DisposeDisplayDeviceContext()
/// <summary>
/// 전체 화면 디바이스 컨텍스트 리소스 해제하기
/// </summary>
private void DisposeDisplayDeviceContext()
{
this.displayGraphics.Dispose();
DeleteDC(this.displayDeviceContextHandle);
}
#endregion
}
}
728x90
반응형
그리드형(광고전용)
'C# > WinForm' 카테고리의 다른 글
[C#/WINFORM/.NET5] 마이크 입력 스펙트로그램 표시하기 (0) | 2021.12.18 |
---|---|
[C#/WINFORM] 사운드 필터링 사용하기 (0) | 2021.12.09 |
[C#/WINFORM] NativeWindow 클래스 : 마우스 캡처 변경시 이벤트 전달하기 (0) | 2021.12.06 |
[C#/WINFORM] 마우스 히트 테스트(Hit Test) 사용하기 (0) | 2021.12.06 |
[C#/WINFORM] 특정 영역에서 마우스 커서 설정하기 (0) | 2021.12.06 |
[C#/WINFORM] 카카오 링크를 사용해 나에게 카카오톡 메시지 보내기 (기능 개선) (0) | 2021.11.24 |
[C#/WINFORM] 누겟 설치 : CefSharp.WinForms (0) | 2021.11.23 |
[C#/WINFORM] 누겟 설치 : CefSharp.Common (0) | 2021.11.23 |
[C#/WINFORM] WebBrowser 클래스 : Internet Explorer의 브라우저 에뮬레이션 모드 구하기 (0) | 2021.11.23 |
[C#/WINFORM] WebBrowser 클래스 : Internet Explorer 버전 11 사용하기 (0) | 2021.11.23 |
댓글을 달아 주세요