>  기사  >  백엔드 개발  >  C# GDI+ 프로그래밍 (5)

C# GDI+ 프로그래밍 (5)

高洛峰
高洛峰원래의
2016-12-17 10:09:471422검색

창의 비클라이언트 영역에 그리는 API 함수를 호출합니다

GDI+의 Graphics 클래스에 FromHdc 함수가 있습니다. 이 함수는 창 장치를 기반으로 Graphics 객체를 생성할 수 있습니다. vc++에서 비클라이언트 영역을 사용하여 그리는 윈도우 클라이언트 영역은 GetWindowDC 및 GetDC 함수에 대한 다른 호출에 지나지 않습니다. 전자는 전체 창 DC를 가져오고 후자는 창 클라이언트 영역 DC를 가져옵니다.

그런 다음 C#에서 GetWindowDC 함수를 호출하여 전체 창 DC를 얻은 다음 FromHdc를 통해 이를 로드하여 전체 창에 대해 그릴 수 있습니다.

C#에서 WINDOWS API를 호출하는 방법 또는 동적 링크 라이브러리(DLL)에서 함수를 호출하는 방법.

VC++와 유사하게 동적 링크 라이브러리를 먼저 가져온 후 다음과 같이 API 함수를 선언합니다.

[System.Runtime.InteropServices.DllImport("User32.dll")]
private static extern IntPtr GetWindowDC(IntPtr hwnd);

물론 위의 내용이 가장 간단하고 아직 언급되지 않은 세부 사항이 있으므로 지금은 그냥 해보고 기본적으로 사용 방법만 알아두면 됩니다. 자세한 내용은 나중에 자세히 설명하겠습니다.

C#에서는 VC++에서 HDC와 HWND를 처리하는 것처럼 API 함수의 매개변수 유형이 다르다는 것을 알 수 있습니다. 여기서 선언할 때 대신 IntPtr을 사용했습니다. C#에는 포인터 개념이 없기 때문에 이를 수행할 수 있는 방법이 없으며, HDC 및 HWND 유형 정의를 확인해보니 둘 다 포인터 유형인 것으로 나타났습니다.

따라서 C#에서는 영역 핸들 HRGN, HICON 아이콘, HFONT 글꼴 핸들 등을 포함하여 이러한 "핸들" 유형이 IntPtr로 대체됩니다.

예제를 살펴보겠습니다. (이전 장에 이어)

public 부분 클래스 Form1: Form
{
//동적 링크 라이브러리를 가져오고 함수를 선언합니다. 이 함수는 Form1 클래스에 선언되어 있습니다.
[System.Runtime.InteropServices.DllImport("User32.dll")]
private static extern IntPtr GetWindowDC(IntPtr hwnd);
//PNG의 불투명 부분을 저장할 경로
private GraphicsPath path = new GraphicsPath();
//PNG 이미지 로드
Bitmap bmp = new Bitmap("d:\Image\win.png");
public Form1()
{
​​ 초기화 구성 요소();
//각 픽셀의 색상 값을 판단하고 그림의 표시 영역을 구합니다
for (int y = 0; y < bmp.Height; y++)
for (int x = 0; x < bmp.Width; x++)
{
Color cor = bmp.GetPixel(x, y);
int argb = cor .ToArgb (); GetBytes(argb);
//픽셀 색상 값이 투명하지 않습니다
if (bargb[3] != 0)
                      //이 픽셀 영역을 경로에 추가
               path.AddRectangle(new Rectangle (x, y, 1, 1));                                                                                             창 표시 영역, 경로를 통해 영역 생성
This.Region = new Region( path);
this.Paint += formPaint;

}
private void formPaint(객체 전송자, PaintEventArgs e)
{
                                                                                                  >                  //Handle은 창 핸들이며 IntPtr 유형입니다.
             IntPtr hdc = GetWindowDC(this.Handle);                                                    Graphics.FromHdc (hdc);
                                                                                          ~                                                        이후보호된 재정의 void OnPaintBackground(PaintEventArgs e)
                                                                            void es.Transparent, .ClientRectangle) ;
                                                                                                                  그것은 몇 가지 문제 또는 많은 문제를 가져올 것입니다. 단지 내가 해결하지 못했을 뿐입니다. 전체 창을 완전히 새로 고치지 않고 창을 이동하거나 창을 최대화하면 이 문제가 발생합니다. 이 문제는 나중에 해결될 것입니다.

관심 있는 친구들도 이 문제를 해결할 수 있습니다.

그리고 창의 클라이언트 영역만 투명 브러시로 채웠습니다. 창 전체(제목 표시줄 포함)를 채우려면 방법은 전체에 그리는 것과 같습니다. window, WindowDC를 가져온 다음

그래픽 개체를 만들고 창 배경을 그립니다.

(여담: vc++에서는 클라이언트 영역과 비클라이언트 영역에 서로 다른 다시 그리기 메시지인 WM_PAINT와 WM_NCPAINT가 있습니다. 이에 주의하세요. 비클라이언트 영역을 새로 고칠 때 클라이언트 영역을 다시 그리지 마세요. , 문제는 없겠지만 효율성에 영향을 미치는 경우 항상 나쁩니다. 가능하면 피하십시오.)

자체 그린 창의 비클라이언트 영역(제목 표시줄, 최대값, 최소화 포함) , 닫기 버튼)

메시지 처리 기능 다시 작성 WndProc

public 부분 클래스 Form1: Form

{

public Form1()

{

InitializeComponent();

       }

protected override void WndProc(ref Message m)

{
if (m.Msg == 0xA3)//WM_NCLBUTTONDBLCLK 제목 메시지 두 번 클릭
MessageBox.Show(" You 제목 표시줄을 두 번 클릭했습니다.");
                                           처리합니다.

메시지에 해당하는 값을 확인하려면 VC++ 컴파일러에서 확인할 수 있습니다. 예를 들어 WM_LBUTTONDOWN을 표시하고 마우스 오른쪽 버튼을 클릭한 다음 정의로 이동을 선택하여 볼 수 있습니다.

m.HWnd는 창 핸들을 저장합니다. m.LParam과 m.WParam은 메시지의 부수적인 정보입니다. CreateWindow 함수의 WPARAM 및 LPARAM 매개 변수에 대한 설명을 참조하세요.



비클라이언트 영역을 직접 그리는 작업량이 정말 너무 많습니다. 여기서는 대략적인 아이디어와 방향만 설명하겠습니다. 미래.

물론 창에 테두리가 있는지 여부 등 다양한 데이터를 계산하는 것이 전제입니다. 그렇다면 테두리의 너비와 높이를 구한 다음 네 개의 테두리의 직사각형 면적을 계산합니다.

마지막으로 창에 최대 및 최소 속성이 있는지 확인하고 세 개의 버튼에 대한 영역을 구합니다.

SystemInformation 클래스는 이러한 데이터를 저장합니다. 예를 들어 SystemInformation.CaptionButtonSize는 제목 표시줄 버튼의 크기를 저장하고 나면

버튼의 영역을 결정할 수 있습니다. , 왜냐하면 이 세 개의 버튼은 테두리의 높이와 너비를 제외하고 모두 창의 오른쪽 상단에 있기 때문입니다.

SystemInformation.CaptionHeight는 제목 표시줄의 높이를 저장하고, 테두리의 높이와 너비는 창의 FormBorderStyle에 따라 결정되는 SystemInformation.BorderSize 또는 SystemInformation.Border3DSize에 저장됩니다. MaximizeBox를 통해 창이 최대화되었는지 여부를 확인할 수 있으며, true인 경우 최대화됩니다.

위의 데이터를 얻은 후 마우스 왼쪽 버튼 메시지 WM_NCLBUTTONDOWN 및 WM_NCLBUTTONUP 등 비클라이언트 영역의 다양한 메시지에 응답합니다.

마우스가 WM_NCMOUSEMOVE 메시지를 이동한 후 셀프 그리기가 시작됩니다.

Rectangle 클래스의 Contains 함수는 점이 직사각형 영역 내에 있는지 여부를 확인할 수 있습니다.

더 많은 C# GDI+ 프로그래밍(5) 관련 기사를 보려면 PHP 중국어 웹사이트를 주목하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.