代码改变世界

win32的一个售票程序,收获有非常的多

2011-10-15 10:23  捣乱小子  阅读(752)  评论(0编辑  收藏  举报

先秀一下我的收获吧!

1、在创建非模态对话框的时,需要用到createdialog函数,第二个参数需要注意是填写对话框的资源标识符(id),之后需要调用showwindow来显示对话框;或者不这么做也行,就是在对话框属性visiable设置为true;

2、hdc变量最好在函数内初始化,别将它直接传入函数;

3、WM_SIZE的wParam参数很有用;

4、关于movewindow

MoveWindow sends the WM_WINDOWPOSCHANGING, WM_WINDOWPOSCHANGED, WM_MOVE, WM_SIZE, and WM_NCCALCSIZE messages to the window.

5、WM_WINDOWPOSCHANGED消息的lParam参数只向一个WINDOWPOS结构体的指针,所以我们可以利用这个指针时刻调整我们的窗口位置或者大小,很有用,

wndpos = (LPWINDOWPOS)lParam;

6、获取对话框内的控件id也因getdlgitem()变的很方便,还有一个getdlgitemid()也很方便;

7、WM_CTLCOLORDLG消息不详细解释啦,直接看msdn:

The WM_CTLCOLORDLG message is sent to a dialog box before the system draws the dialog box. By responding to this message, the dialog box can set its text and background colors using the specified display device context handle.

直接上代码了,功能还不是很完善的,算法也算简单,作为一个win32的初学者,也有那么一点点的成就感。

#include <windows.h>
#include "resource.h"

#define CLSNAME "Ticket"
#define WNDNAME "售票系统"

#define XGAP cxChar*5
#define YGAP cyChar

static int cxChar,cyChar;
BOOL bDraw[8][7]={0};
HWND iBtnFirst;
WNDPROC BTNPROC[8][7];
HWND hwndOption;
static BOOL bShine;

void Draw(HWND parent,HWND btn,BOOL flag);
LRESULT CALLBACK WindowProc(HWND hwnd,
							UINT uMsg,
							WPARAM wParam,
							LPARAM lParam
							);
LRESULT CALLBACK BtnProc(HWND hwnd,
						 UINT uMsg,
						 WPARAM wParam,
						 LPARAM lParam
							);
INT_PTR CALLBACK OptionProc(HWND hwndDlg,
    UINT uMsg,
    WPARAM wParam,
    LPARAM 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) (COLOR_BTNFACE+1);
	wndclass.lpszMenuName = NULL ;
	wndclass.lpszClassName = clsname ;

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

	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);

	hwndOption = ::CreateDialog(hInstance,
		TEXT("OPTION"),hwnd,OptionProc);
	::ShowWindow(hwndOption,SW_SHOW);

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

void Draw(HWND parent,HWND btn,BOOL flag)
{
	HDC hdc;
	RECT rect;
	HBRUSH hBrush;
	POINT a;
	POINT b;

	hdc = ::GetDC(parent);

	::GetWindowRect(btn,&rect);
	a.x = rect.right;
	a.y = rect.top;
	b.x = rect.right;
	b.y = rect.bottom;

	::ScreenToClient(parent,&a);
	::ScreenToClient(parent,&b);

	if(flag)
	{
		hBrush = ::CreateSolidBrush(RGB(255,0,0));
		::SetWindowText(
		btn,TEXT("座位售出"));
	}
	else 
	{
		hBrush = ::CreateSolidBrush(RGB(128,255,128));
	}

	::SelectObject(hdc,hBrush);
	::Ellipse(hdc,a.x,a.y,b.x+XGAP,b.y);
	::ReleaseDC(parent,hdc);
}

LRESULT CALLBACK WindowProc(HWND hwnd,
							UINT uMsg,
							WPARAM wParam,
							LPARAM lParam
							)
{
	HDC hdc;
	PAINTSTRUCT ps;
	int i,j;
	RECT rect;
	static HWND hwndBtn[8][7];
	static BOOL bFlag[8][7];
	static HBRUSH hBrush;
	static int iRow,iCol,iBtn;
	TCHAR szBuffer[9];
	static WINDOWPOS  * wndpos;
	int mvX,mvY,mvCx,mvCy;
	int iOptionAdult,iOptionChild;

	switch(uMsg)
	{
	case	WM_CREATE:
		cxChar = LOWORD(::GetDialogBaseUnits());
		cyChar = HIWORD(::GetDialogBaseUnits());

		for(i=0;i<8;i++)
			for(j=0;j<7;j++)
			{			
				hwndBtn[i][j] = ::CreateWindow(TEXT("button"),TEXT("未售出"),
					WS_CHILD|WS_VISIBLE,

					XGAP*(j+1)+cxChar*9*j,YGAP*(i+1)+cyChar*7/4*i,

					cxChar*9,cyChar*7/4,
					hwnd,HMENU(i*10+j),NULL,NULL);

				::wsprintf(szBuffer,TEXT("%d行%d座"),i+1,j+1);
				::SetWindowText(hwndBtn[i][j],szBuffer);
			}
			return 0;

	case WM_SIZE:
		if(wParam!=SIZE_MINIMIZED
			||wParam!=SIZE_RESTORED)
		{
			mvX = (::GetSystemMetrics(SM_CXSCREEN)-
				(cxChar*9*7+9*XGAP))/2;
			mvY = 	(::GetSystemMetrics(SM_CYSCREEN)-
				(cyChar*7/4*8+11*YGAP))/2;
			mvCx = cxChar*9*7+9*XGAP;
			mvCy = cyChar*7/4*8+11*YGAP+YGAP*2;

			::MoveWindow(hwnd,mvX,mvY,mvCx,mvCy,false);

			::GetWindowRect(hwndOption,&rect);
			::MoveWindow(hwndOption,
				mvX,mvY+rect.bottom-rect.top,
				rect.right-rect.left,
				rect.bottom-rect.top,
				TRUE);
		}
		return 0;

	case WM_WINDOWPOSCHANGED:
		wndpos = (LPWINDOWPOS)lParam;
		::GetWindowRect(hwndOption,&rect);

		::MoveWindow(hwndOption,
			wndpos->x,
			wndpos->y+wndpos->cy,

			rect.right-rect.left,
			rect.bottom-rect.top,
			TRUE);
		return 0;

	case WM_COMMAND:
		iBtn = ::GetWindowLong((HWND)lParam,GWL_ID);
		iRow = iBtn / 10;
		iCol = iBtn % 10;

		iOptionAdult = (int)::SendMessage(::GetDlgItem(hwndOption,IDC_ADULT),
			BM_GETCHECK,0,0);
		iOptionChild = (int)::SendMessage(::GetDlgItem(hwndOption,IDC_CHILD),
			BM_GETCHECK,0,0);

		if(!iOptionAdult&&!iOptionChild)
		{
			::MessageBox(hwnd,TEXT("请标记售票类型!"),
				TEXT("提示"),MB_OK|MB_ICONEXCLAMATION);
			::SetFocus(hwndOption);
				return 0;
		}

		if(!bDraw[iRow][iCol]&&
			HIWORD(wParam) == BN_CLICKED)
		{
			bDraw[iRow][iCol] = TRUE;
			::Draw(hwnd,(HWND)lParam,TRUE);
			::SetFocus(hwnd);		
			::SendMessage(hwndOption,WM_COMMAND,1,1);
			return 0;
		}
		break;

		//后来才发现这个消息只适用于自绘按钮
		/*case WM_CTLCOLORBTN:
		if((HWND)lParam==hwndBtn&&wParam==1)
		{
		return (LRESULT)hBrush;
		}
		break;*/

	case WM_DESTROY:
		::PostQuitMessage(0);
		return 0;

	case WM_PAINT:
		hdc = ::BeginPaint(hwnd,&ps);
		for(i=0;i<8;i++)
			for(j=0;j<7;j++)
			{
				if(bDraw[i][j])
					::Draw(hwnd,hwndBtn[i][j],TRUE);
				else
					::Draw(hwnd,hwndBtn[i][j],FALSE);
			}
			::EndPaint(hwnd,&ps);
			return 0;
	}
	return ::DefWindowProc(hwnd,uMsg,wParam,lParam);
}

INT_PTR CALLBACK OptionProc(HWND hwndDlg,
    UINT uMsg,
    WPARAM wParam,
    LPARAM lParam
)
{
	static HWND hwndAdult,hwndChild;
	HBRUSH hBrush;
	HWND hwndParent;
	RECT rect;

	switch(uMsg)
	{
		//原来可以在这里修改大小的
	case WM_INITDIALOG:
		hwndParent = ::GetParent(hwndDlg);
		::GetWindowRect(hwndParent,&rect);
		::SetWindowPos(hwndDlg,NULL,
			rect.left,rect.bottom,
			0,0,
			SWP_NOSIZE);

		return 0;

	case WM_CTLCOLORDLG:
			hBrush = ::CreateSolidBrush(RGB(0,128,255));
		return (INT_PTR)hBrush;

	case WM_COMMAND:
		if(wParam==1&&lParam==1)
		{
			::SendMessage(::GetDlgItem(hwndDlg,IDC_ADULT),
				BM_SETCHECK,0,0);
			::SendMessage(::GetDlgItem(hwndDlg,IDC_CHILD),
				BM_SETCHECK,0,0);
		}

		switch(LOWORD(wParam))
		{
		case IDC_ADULT:
			//这里设置数据
			return TRUE;
		case IDC_CHILD:
			//这里设置数据
			return TRUE;
		}
		break;
	}
	return FALSE;
}