>  기사  >  운영 및 유지보수  >  Win32 SDK 기본 사항 (12) WM_PAINT 메시지 처리(그림)

Win32 SDK 기본 사항 (12) WM_PAINT 메시지 처리(그림)

黄舟
黄舟원래의
2017-06-06 10:11:467991검색

1. 소개

컴퓨터에서는 창, 대화 상자, 그림 및 모든 텍스트를 포함하여 화면에 표시되는 거의 모든 것이 그려지며 이러한 개체 뉴스를 그릴 때 시스템에 의해 WM_PAINT 메시지가 트리거됩니다. 우리가 컴퓨터에서 수행하는 거의 모든 작업은 이 메시지를 트리거하며 이는 Windows에서 가장 중요한 메시지 중 하나이기도 합니다. 이 기사에서는 포괄적인 연구를 위해 이 메시지를 실험하는 데 중점을 둡니다.

2. WM_PAINT의 기본

2.1 매크로 정의

#define WM_PAINT                        
0x000F

2.2 매개변수 전달

우리는 sendmessage/postmessage를 사용하여 메시지를 보낼 때 WPARAM과 LPARAM 두 매개변수가 종종 전달된다는 것을 알고 있습니다. GetMessage가 사용됩니다. 또는 PeekMessage가 메시지를 수신하면 이 두 매개변수도 수신하게 됩니다. 이러한 메시지 중 일부는 마우스 위치, 창 길이 및 너비 등과 같은 매개변수에 필요한 정보를 전달합니다. WM_PAINT의 이 두 매개변수는 비어 있으며 메시지를 전달하지 않습니다.

2.3 트리거 타이밍

이 메시지의 트리거 타이밍을 얻기 위해 먼저 Win32 창 프로젝트를 테스트 개체로 만듭니다. 창 처리 함수 는 다음과 같이 정의됩니다.

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)  
{  
	switch (uMsg)  
	{  
	case WM_DESTROY:  
		PostQuitMessage(0);//可以使GetMessage返回0  
		break;
	case  WM_PAINT:
		{
			WriteConsole(hOutput,"WM_PAIN\n",10,NULL,NULL);
		}
		break;
	default:  
		break;  
	}  
	return DefWindowProc(hWnd, uMsg, wParam, lParam);  
}

WM_PAINT 처리 문에서 "WM_PAINTn"의

문자열 이 콘솔의 표준 출력에 기록되어 WM_PAINT 메시지가 트리거되는지 확인합니다. WM_PAINT의 트리거 타이밍을 각각 확인해 보겠습니다.

1 프로그램이 시작되면 창이 그려질 때 트리거됩니다.

프로그램을 시작하면 창을 그려야 하기 때문에 WM_PAINT 메시지가 실행됩니다.


2.

창 크기가 조정될 때 창을 계속 다시 그려야 하기 때문에 WM_PAINT 메시지가 지속적으로 트리거됩니다.


3 WM_PAINT 메시지는 다음과 같은 경우에 트리거되지 않습니다. 최소화했지만 최소화에서 복원됩니다.

아래 그림은 창을 최소화하는 과정에서 두 번 더 문자열이 인쇄되는 것을 볼 수 있습니다


4 . WM_PAINT 메시지를 최대화하면 트리거됩니다.

그림이 최대화되고 복원되면 아래 그림과 같이 WM_PAINT 메시지가 한 번 트리거됩니다.


5. 화면에 들어가면 WM_PAINT 메시지가 트리거되지 않지만 뒤로 당겨지면 WM_PAINT 메시지가 계속해서 트리거됩니다.

아래 스크린샷은 창이 화면으로 다시 당겨지면, 창은 지속적으로 다시 그려져 WM_PAINT 메시지를 트리거합니다. A6, wm_paint 메시지의 변형을 사용하여 Inval 、IdateRect의 추론 함수를 사용합니다. NULL이면 시스템은 함수가 반환되기 전에 모든 창을 다시 그린 다음 WM_ERASEBKGND 및 WM_PAINT를 창 프로시저 처리 함수에 보냅니다.

lpRect: 유효하지 않은 영역의 직사각형 표현입니다. 직사각형의 크기를 저장하는

구조 포인터입니다. NULL인 경우 전체 윈도우 클라이언트 영역이 업데이트 영역에 추가됩니다.
bErase: 잘못된 직사각형이 유효한 것으로 표시된 후 영역을 다시 그릴지 여부를 나타냅니다. 다시 그릴 때 미리 정의된 브러시를 사용합니다. TRUE가 지정된 경우 다시 그리기가 필요합니다.

반환 값:

함수가 성공하면 0이 아닌 값을 반환하고, 그렇지 않으면 0 값을 반환합니다. InvalidateRect 함수의 기능을 확인하려면 창 처리 함수에 WM_LBUTTONDOWN 메시지 처리를 추가하고 마우스 왼쪽 버튼을 클릭할 때마다 InvalidateRect를 호출해야 합니다.

//窗口处理函数  
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)  
{  
	switch (uMsg)  
	{  
	case WM_DESTROY:  
		PostQuitMessage(0);//可以使GetMessage返回0  
		break;
	case  WM_PAINT:
		{
			WriteConsole(hOutput,"WM_PAIN\n",10,NULL,NULL);
		}
	case WM_LBUTTONDOWN:
		{
			InvalidateRect(hWnd,NULL,true);
		}
		break;
	default:  
		break;  
	}  
	return DefWindowProc(hWnd, uMsg, wParam, lParam);  
}

        下图为执行结果,点击了3次鼠标左键,触发了3次WM_PAINT消息。

总结:

        触发WM_PAINT消息的本质是改变窗口对应的显存的大小就触发一次,我们进行的每一次窗口最大化、最小化并恢复都是因为改变了窗口的显存而触发了该消息。在我们向屏幕外面拖动窗口时,这点比较特殊,窗口的显存是在一点点被擦除的,此时不会触发WM_PAINT,但是拉回窗口后,显存需要将擦除的部分重新绘制,这就又会触发一次该消息。而InvalidateRect函数,就是通过强制的清除并重绘显存来实现触发WM_PAINT消息。

三、WM_PAINT消息的处理

        我们尝试处理WM_PAINT消息,并在窗口上绘制一个矩形,绘图步骤如下:

1、开始绘图处理

HDC BeginPaint(
        HWND hwnd,//绘图窗口
        LPPAINTSTRUCT  lpPaint
	);

        我们利用BeginPaint获取绘图设备的句柄---一个HDC对象,然后在改绘图设备上进行绘制。

2、利用HDC对象进行绘图

3、结束绘图处理

Bool EndPoint(
        HWND hWnd,
        CONST PAINTSTRUCT *lpPaint
);

        绘制过程参考下面的代码:

//窗口处理函数  
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)  
{  
	
	switch (uMsg)  
	{  
	case WM_DESTROY:  
		PostQuitMessage(0);//可以使GetMessage返回0  
		break;
	case  WM_PAINT:
		{
			PAINTSTRUCT pt;
			HDC hdc;
			hdc=BeginPaint(hWnd,&pt);
			Rectangle(hdc,0,0,100,100);
			EndPaint(hWnd,&pt);
		}
	case WM_LBUTTONDOWN:
		{
			//InvalidateRect(hWnd,NULL,true);
		}
		break;
	default:  
		break;  
	}  
	return DefWindowProc(hWnd, uMsg, wParam, lParam);  
}

        执行结果如下,我们成功绘制了一个矩形:


위 내용은 Win32 SDK 기본 사항 (12) WM_PAINT 메시지 처리(그림)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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