본문 바로가기
프로그래밍/API

API-WindowLong

by 리뷰하는 (게임)프로그래머_리프TV 2010. 4. 24.


CreateWindow로 윈도우를 만들 때 설정했던 윈도우의 속성들을 실행중에 조사하거나 바꾸고자 할때

LONG GetWindowLong(HWND hWnd, int nIndex);
LONG SetWindowLong(HWND hWnd, int nIndex, LONG dwNewLong);

이다.

이는 32비트용이고,

64비트를 지원하는 새로운 함수 원형은 다음과 같다.

LONG_PTR GetWindowLongPtr(HWND hWnd, int nIndex);
LONG_PTR SetWindowLongPtr(HWND hWnd, int nIndex, LONG_PTR dwNewLong);

쓰는 법은 똑같으며, 함수명 뒤에 Ptr이 붙고 LONG대신 LONG_PTR을 쓰는 정도의 차이밖에 없다고 한다.

#include <windows.h>

LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );
HINSTANCE g_hInst;
LPCTSTR lpszClass = TEXT("ClassLong");

int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
					 LPSTR lpszCmdParam, int nCmdShow )
{
	HWND hWnd;
	MSG Message;
	WNDCLASS WndClass;
	g_hInst = hInstance;

	WndClass.cbClsExtra = 0;
	WndClass.cbWndExtra = 0;
	WndClass.hbrBackground = (HBRUSH)GetStockObject( COLOR_WINDOW+1 );
	WndClass.hCursor = LoadCursor( NULL, IDC_ARROW );
	WndClass.hIcon = LoadIcon( NULL, IDI_APPLICATION );
	WndClass.hInstance = hInstance;
	WndClass.lpfnWndProc = WndProc;
	WndClass.lpszClassName = lpszClass;
	WndClass.lpszMenuName = NULL;
	WndClass.style = CS_HREDRAW | CS_VREDRAW;
	RegisterClass( &WndClass );

	hWnd = CreateWindow(lpszClass, lpszClass, WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
		NULL, (HMENU)NULL, hInstance, NULL );
	ShowWindow( hWnd, nCmdShow );

	while( GetMessage( &Message, NULL, 0, 0 ) )
	{
		TranslateMessage( &Message );
		DispatchMessage( &Message );
	}
	return (int)Message.wParam;
}

LRESULT CALLBACK WndProc( HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam )
{
	static HBRUSH hRed, hGreen, hBlue;
	static HBRUSH NowBrush;
	static LONG_PTR LongPtr;
	static HCURSOR hCurArrow, hCurCross;
	static HCURSOR NowCursor;

	switch( iMessage )
	{
	case WM_CREATE:
		hRed = CreateSolidBrush( RGB( 255, 0, 0 ) );
		hGreen = CreateSolidBrush( RGB( 0, 255, 0 ) );
		hBlue = CreateSolidBrush( RGB( 0, 0, 255 ) );
		NowBrush = hRed;
		NowCursor = LoadCursor( NULL, IDC_ARROW );
		hCurArrow = LoadCursor( NULL, IDC_ARROW );
		hCurCross = LoadCursor( NULL, IDC_CROSS );
		return 0;
	case WM_LBUTTONDOWN:
		if( NowBrush == hRed ) NowBrush = hGreen;
		else if( NowBrush == hGreen ) NowBrush = hBlue;
		else if( NowBrush == hBlue ) NowBrush = hRed;
		SetClassLongPtr( hWnd, GCLP_HBRBACKGROUND, (LONG_PTR)NowBrush );
		InvalidateRect( hWnd, NULL, TRUE );
		SetClassLongPtr( hWnd, GCLP_HCURSOR, (LONG_PTR)NowCursor );
		return 0;
	case WM_RBUTTONDOWN:
		if( NowCursor == hCurArrow ) 
			NowCursor = hCurCross;
		else 
			NowCursor = hCurArrow;
		SetClassLongPtr( hWnd, GCLP_HCURSOR, (LONG_PTR)NowCursor );

		return 0;
	case WM_DESTROY:
		DeleteObject( hRed );
		DeleteObject( hGreen );
		DeleteObject( hBlue );
		PostQuitMessage(0);
		return 0;
	}
	return( DefWindowProc( hWnd, iMessage, wParam, lParam));
}​


특별한 기능은 없고, 실행 후 왼쪽 버튼을 누르면, 색상이 변경되고,
오른쪽 버튼을 누르면 마우스 포인터가 변경되는 간단한 예제이다.
특별히 살펴 볼 점은 SetClassLongPtr의 2번째 인자인데, 예제에서는 백그라운드를 관리하는 GCLP_HBRBACKGROUND와
커서를 관리하는 GCLP_HCURSOR 를 사용했었따는 점이다.

실행 화면은 pass 어차피 보여봤자, 백그라운드 색상 밖에 없으니까.

'프로그래밍 > API' 카테고리의 다른 글

API-더블 버퍼링  (0) 2010.05.10
API-ChildWnd  (0) 2010.04.24
API-WNDCLASSEX  (0) 2010.04.24
API-대화상자  (0) 2010.04.24
API-Control(2)  (0) 2010.04.24