代码改变世界

win32自定义控件(虽然不美观,但对理解很有好处)

2011-10-09 20:26  捣乱小子  阅读(3491)  评论(0编辑  收藏  举报

win32的自定义控件不是很美观,但是对控件有个比较底层的认识,值了。

#include <windows.h>
#include "resource.h"
#define CLSNAME "About3"
#define WNDNAME "about3 demo"

LRESULT CALLBACK WindowProc(HWND hwnd,
							UINT uMsg,
							WPARAM wParam,
							LPARAM lParam
							);
LRESULT CALLBACK EllipPushWndProc(HWND,UINT,WPARAM,LPARAM);
BOOL CALLBACK DialogProc(HWND,UINT,WPARAM,LPARAM);

int WINAPI WinMain (HINSTANCE hInstance,
					HINSTANCE hPrevInstance,
					PSTR szCmdLine, 
					int iCmdShow)
{
	static TCHAR clsname[] = TEXT(CLSNAME);
	WNDCLASS wndclass;
	wndclass.style = CS_HREDRAW | CS_VREDRAW ;
	wndclass.lpfnWndProc = WindowProc ;
	wndclass.cbClsExtra = 0 ;
	wndclass.cbWndExtra = 0 ;
	wndclass.hInstance = hInstance ;
	wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
	wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
	wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
	wndclass.lpszMenuName = clsname ;
	wndclass.lpszClassName = clsname ;

	if(!::RegisterClass(&wndclass))
	{
		MessageBox ( NULL, 
			TEXT ("This program requires Windows NT!"),
			clsname, 
			MB_ICONERROR) ;
		return 0 ;
	}

	//注册自定义窗口类
	wndclass.style = CS_HREDRAW|CS_VREDRAW;
	wndclass.lpfnWndProc = EllipPushWndProc;//here
	wndclass.cbClsExtra = 0;
	wndclass.cbWndExtra = 0;
	wndclass.hInstance = hInstance;
	wndclass.hIcon = NULL;
	wndclass.hCursor = ::LoadCursor(NULL,IDC_ARROW);
	wndclass.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);//here
	wndclass.lpszMenuName = NULL;
	wndclass.lpszClassName = TEXT("EllipPush");//here
	//资源id必须和类名一样(不分大小写)

	::RegisterClass(&wndclass);//注册

	HWND hwnd;
	hwnd = ::CreateWindow(clsname,TEXT(WNDNAME),
		WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT,CW_USEDEFAULT,
		CW_USEDEFAULT,CW_USEDEFAULT,
		NULL,NULL,hInstance,NULL);
	::ShowWindow(hwnd,SW_SHOW);
	::UpdateWindow(hwnd);

	MSG msg;
	while(::GetMessage(&msg,NULL,0,0)){
		::TranslateMessage(&msg);
		::DispatchMessage(&msg);
	}
	return msg.wParam;
}

LRESULT CALLBACK WindowProc(HWND hwnd,
							UINT uMsg,
							WPARAM wParam,
							LPARAM lParam
							)
{
	static HINSTANCE hInstance;

	switch(uMsg)
	{
	case WM_CREATE:
		hInstance = (HINSTANCE)::GetWindowLong(hwnd,GWL_HINSTANCE);
		return 0;

	case WM_COMMAND:
		switch(LOWORD(wParam))
		{
		case IDM_APP_ABOUT:
			DialogBox(hInstance,TEXT("AboutBox"),hwnd,DialogProc);
			return 0;
		}
		break;

	case WM_KEYDOWN:
		switch(wParam)
		{
		case VK_RETURN:
			::SendMessage(hwnd,WM_COMMAND,IDM_APP_ABOUT,0);
			return 0;
		}
		break;

	case WM_DESTROY:
		::PostQuitMessage(0);
		return 0;
	}
	return ::DefWindowProc(hwnd,uMsg,wParam,lParam);
}

BOOL CALLBACK DialogProc(HWND hwndDlg,
						 UINT uMsg,
						 WPARAM wParam,
						 LPARAM lParam
						 )
{
	switch(uMsg)
	{
	case WM_INITDIALOG:
		return true;

	case WM_COMMAND:
		switch(LOWORD(wParam))
		{
		case IDOK:
		case IDCANCEL:
			::EndDialog(hwndDlg,0);
			return true;
		}
		break;
	}
	return FALSE;
}

//自定义控件过程
LRESULT CALLBACK EllipPushWndProc(HWND hwndDlg,
						 UINT uMsg,
						 WPARAM wParam,
						 LPARAM lParam
						 )
{
	TCHAR szText[40];
	HBRUSH hBrush;
	HDC hdc;
	PAINTSTRUCT ps;
	RECT rect;

	switch(uMsg)
	{
	case WM_PAINT:
		::GetClientRect(hwndDlg,&rect);
		::GetWindowText(hwndDlg,szText,sizeof(szText));

		hdc = ::BeginPaint(hwndDlg,&ps);

		hBrush = ::CreateSolidBrush(::GetSysColor(COLOR_BTNFACE));
		hBrush = (HBRUSH)::SelectObject(hdc,hBrush);
		::SetBkColor(hdc,GetSysColor(COLOR_BTNFACE));//设置背景颜色
		::SetTextColor(hdc,GetSysColor(COLOR_WINDOWTEXT));//设置文本颜色

		::Rectangle(hdc,rect.left,rect.top,rect.right,rect.bottom);//着色
		::DrawText(hdc,szText,-1,&rect,
			DT_SINGLELINE|DT_CENTER|DT_VCENTER);//又收获一个财富

		::DeleteObject(::SelectObject(hdc,hBrush));
		return 0;

	case WM_KEYUP:
		if(wParam != VK_SPACE)//这里如果是空格键就fall through
			break;

		//如果点击了鼠标左键,就给主窗口发消息
	case WM_LBUTTONDOWN:
		::SendMessage(::GetParent(hwndDlg),WM_COMMAND,
			MAKEWORD(::GetWindowLong(hwndDlg,GWL_ID),0),
			(LPARAM)hwndDlg);
		return 0;
	}
	return ::DefWindowProc(hwndDlg,uMsg,wParam,lParam);
}