总结一、VC窗口的建立

// 涉及到的函数/结构(部分),不清楚用法的,直接查msdn
int WINAPI WinMain(
	HINSTANCE hInstance,      // handle to current instance
	HINSTANCE hPrevInstance,  // handle to previous instance
	LPSTR lpCmdLine,          // command line
	int nCmdShow              // show state
);

LRESULT CALLBACK WindowProc(
	HWND hwnd,      // handle to window
	UINT uMsg,      // message identifier
	WPARAM wParam,  // first message parameter
	LPARAM lParam   // second message parameter
);

HWND CreateWindow(
	LPCTSTR lpClassName,  // registered class name
	LPCTSTR lpWindowName, // window name
	DWORD dwStyle,        // window style
	int x,                // horizontal position of window
	int y,                // vertical position of window
	int nWidth,           // window width
	int nHeight,          // window height
	HWND hWndParent,      // handle to parent or owner window
	HMENU hMenu,          // menu handle or child identifier
	HINSTANCE hInstance,  // handle to application instance
	LPVOID lpParam        // window-creation data
);

typedef struct tagMSG {
	HWND   hwnd; 
	UINT   message; 
	WPARAM wParam; 
	LPARAM lParam; 
	DWORD  time; 
	POINT  pt; 
} MSG, *PMSG; 

// 一个简单的Win32应用程序
#include <windows.h>

// 声明窗口过程函数
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);

// 定义一个全局变量,作为窗口类名
TCHAR szClassName[] = TEXT("SimpleWin32");

// 应用程序主函数
int WINAPI WinMain(HINSTANCE hInstance,
				   HINSTANCE hPrevInstance,
				   LPSTR plCmdLine,
				   int nCmdShow)
{
	// 1)设计窗口类
	WNDCLASS wndclass;
	wndclass.style = CS_HREDRAW | CS_VREDRAW;
	wndclass.lpfnWndProc = WndProc; // 关联窗口过程函数
	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  = NULL;        // 菜单
	wndclass.lpszClassName = szClassName; // 类名称
	
	// 2)注册窗口类
	if (!RegisterClass(&wndclass))
	{
		MessageBox(NULL, TEXT ("RegisterClass Fail!"), 
			szClassName, MB_ICONERROR);
		return 0;
	}

	// 3)建立窗口
	HWND hwnd = CreateWindow(szClassName,     // 窗口类名称
		TEXT("The Simple Win32 Application"), // 窗口标题 
		WS_OVERLAPPEDWINDOW,// 窗口风格,即通常我们使用的windows窗口样式
		CW_USEDEFAULT,      // 指定窗口的初始水平位置,即屏幕坐标系的窗口的左上角的X坐标
		CW_USEDEFAULT,      // 指定窗口的初始垂直位置,即屏幕坐标系的窗口的左上角的Y坐标
		CW_USEDEFAULT,      // 窗口的宽度
		CW_USEDEFAULT,      // 窗口的高度
		NULL,               // 父窗口句柄
		NULL,               // 窗口菜单句柄
		hInstance,          // 实例句柄
		NULL);
	
	// 4)显示更新窗口
	ShowWindow(hwnd, nCmdShow);// 显示窗口
	UpdateWindow(hwnd);        // 更新窗口
	
	// 消息循环
	MSG msg;
	BOOL bRet;
	while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0) //从消息队列中取消息 
	{
		if (bRet == -1)
		{
			// handle the error and possibly exit
		}
		else
		{
			TranslateMessage(&msg);	 // 转换消息
			DispatchMessage(&msg);	 // 派发消息			
		}

	}

/*	while(true)
	{
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) // 从消息队列中取消息
		{
			// handle the error and possibly exit
			if (bRet == -1)
				return -1;
			if (msg.message == WM_QUIT)
				break;
			TranslateMessage (&msg);  // 转换消息
			DispatchMessage (&msg);	  // 派发消息
		}
		else
		{
			WaitMessage();
		}
	}*/ 

	return msg.wParam;
}

// 消息处理函数
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
	case WM_DESTROY:
		// 当用户关闭窗口,窗口销毁,程序需结束,发退出消息,以退出消息循环
		PostQuitMessage(0);
		break;
	default:
		// 其他消息交给由系统提供的缺省处理函数
		return DefWindowProc(hwnd, message, wParam, lParam);
	}

	return 0;
}


总结
1、窗口创建的过程

(1)设计窗口类;
(2)注册窗口类;
(3)建立窗口;
(4)显示更新窗口。

2、函数调用约定(Calling convention)
__stdcall与__cdecl是两种不同的函数调用约定,定义了函数参数入栈的顺序,由调用函数还是被调用函数将参数弹出栈,以及产生函数修饰名的方法。Win32的API函数遵循__stdcall调用约定。在VC++开发环境中,默认的编译选项是cdecl,对于那些遵循__stacall调用约定的函数,在声明时需要显式地加上。

(_cdecl是C Declaration的缩写,表示C语言默认的函数调用方法:所有参数从右到左依次入栈,这些参数由调用者清除,称为手动清栈。被调用函数不需要求调用者传递多少参数,调用者传递过多或者过少的参数,甚至完全不同的参数都不会产生编译阶段的错误。 
    _stdcall是Standard Call的缩写,是C++的标准调用方式:所有参数从右到左依次入栈,如果是调用类成员的话,最后一个入栈的是this指针。这些堆栈中的参数由被调用的函数在返回后清除,称为自动清栈。函数在编译的时候就必须确定参数个数,并且调用者必须严格的控制参数的生成,不能多,不能少,否则返回后会出错。

    PASCAL约定和C约定正好相反,它规定参数是从左向右传递,由被调用者恢复堆栈。Win16采用了PASCAL约定, 因为PASCAL约定产生的代码量要小。

参考:《VC++深入详解》孙鑫

虽大部分内容是copy,但也算是一种总结提炼吧!微笑希望坚持!

你可能感兴趣的:(总结一、VC窗口的建立)