Visual Studio直接创建一个空项目

控件的创建请参考:http://www.qingzhouquanzi.com/287.html

新建一个 后缀为 .c 或者 .cpp文件

#include <windows.h>
//如果出现该符号在函数中被引用需要配置:项目-》属性->配置属性->连接器=》系统  子系统   设置为  窗口 (/SUBSYSTEM:WINDOWS)
//WINAPI代表_stdcall参数的传递顺序,从右到左以此入栈,并且在函数返回前清空堆栈

LRESULT CALLBACK 窗口过程(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM LParam);


//WINAPI代表_stdcall参数的传递顺序,从右到左以此入栈,并且在函数返回前清空堆栈
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){

	//1.设计窗口
	//2.注册窗口
	//3.创建窗口
	//4.显示和更新
	//5通过循环取消息
	//6处理消息


	//第一步:设计窗口
	WNDCLASS wc;
	wc.cbClsExtra = 0;//类的额外内存
	wc.cbWndExtra = 0;//窗口的额外内存
	wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);//设置背景
	wc.hCursor = LoadCursor(NULL, IDC_HAND);//设置光标 如果第一个参数为null,代表使用系统提供的光标
	wc.hIcon = LoadIcon(NULL, IDI_ERROR);//图标,如果第一个参数为null,代表使用系统提供的光标
	wc.hInstance = hInstance;//实例句柄 传入形参即可
	wc.lpfnWndProc = 窗口过程; //回调函数
	wc.lpszClassName = TEXT("win");//窗口类名
	wc.lpszMenuName = NULL;//菜单名称
	wc.style = CS_HREDRAW;// 0;//0代表默认风格


	//第二部:注册窗口类
	RegisterClass(&wc);

	//第三部:创建窗口(返回之前发送WM_CREATE)
	HWND hWndParent = CreateWindow("win","纯API创建窗口",WS_OVERLAPPEDWINDOW,50,50,500,500,NULL,NULL,hInstance,NULL);

	//第四部:显示
	ShowWindow(hWndParent, SW_SHOWNORMAL);
	//更新窗口(发送WM_PAINT)
	UpdateWindow(hWndParent);

	//第五步:通过循环取消息
	
	//msg结构:
	//HWND        hwnd;		主窗口句柄
	//UINT        message;	消息名称
	//WPARAM      wParam;	附加消息 键盘消息
	//LPARAM      lParam;	附加消息 鼠标消息(按键消息)
	//DWORD       time;		消息产生的时间
	//POINT       pt;		附加消息 鼠标消息(位置xy)
	MSG msg;



	while (GetMessage(&msg, NULL, 0, 0))//  参数一:消息指针 参数2:null代表捕获所有窗口 3和4 填写0代表捕获所有消息
	{
		//翻译消息
		TranslateMessage(&msg);//翻译消息是为了处理一些组合按键
		//分发消息
		DispatchMessage(&msg);
	}
	
	return true; 
	
} 



LRESULT CALLBACK 窗口过程(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM LParam){  //消息所处的窗口句柄,具体消息名称 WM_xxxx消息
	switch (uMsg)
	{
		case WM_CLOSE:
			DestroyWindow(hwnd);//销毁窗口 但是不是结束进程,而是发送另一个消息:WM_DESTROY
			break;
		case WM_DESTROY:
			PostQuitMessage(0); //发送退出消息,发完此消息后,在while死循环里 GetMessage() 获取到的就是 false了.就会结束程序!
			break;
		case WM_LBUTTONDOWN:
		{  //如果C语言,需要把这些不在一行的代码括起来.
			int x = LOWORD(LParam);
			int y = HIWORD(LParam);

			char buf[1024];
			wsprintf(buf,TEXT("x=%d,y=%d"), x, y);
			MessageBox(hwnd, buf, TEXT("鼠标左键被按下"), MB_OK);
			break;
		}
		case WM_PAINT:
		{
			PAINTSTRUCT ps;//绘图结构体
			HDC hdc=BeginPaint(hwnd, &ps);
			TextOut(hdc, 100, 100, TEXT("hello"), strlen("hello"));
			EndPaint(hwnd,&ps);
			break;
		}


	}	

	//消息一般都是 WM_开头的,可以从API常量里查询!
	/*返回值用默认的处理方式*/
	return DefWindowProc(hwnd, uMsg, wParam, LParam);
}

扩展阅读:

窗口类WNDCLASS

窗口类WNDCLASS是是Windows中用于创建窗口的模板。每一个窗口类都有一个窗口过程

(WndProc),负责处理发送该类窗口的所有消息。一个应用程序在创建某个类型的窗口前,必须

首先注册该“窗口类”(注意,这里不是C++类的类)。窗口类有三种:


系统窗口类中一部分是系统内部使用的,而另一部分是可以供系统所有进程使用的,这些窗口类就

是基本的控件窗口类。


应用程序全局窗口类,就是注册窗口类时以CS_GLOBALCLASS标志注册的窗口类,这个窗口类在这

个进程中,所有模块都可以使用。模块一般是dll模块。我们知道的程序的皮肤库,很多都是以这种

形式实现的,dll中注册的应用程序全局窗口类,我们程序就可以直接使用这些漂亮的皮肤库提供的

控件了。


应用程序局部窗口类则是没有CS_GLOBALCLASS标志注册的窗口类,这个窗口类只在模块范围内使

用。我们的EXE如果加载了其他的dl模块,此时EXE的主线程注册的应用程序局部窗口类对于dll来

说,是看不见的,也就不能使用这个局部窗口类来创建窗口。

扩展阅读 如何创建两个窗口,共用一个窗口过程

只需要在第三步,和第四部多加一份即可


	//第三部:创建窗口(返回之前发送WM_CREATE)
	HWND hWndParent = CreateWindow("win", "纯API创建窗口", WS_OVERLAPPEDWINDOW, 50, 50, 500, 500, NULL, NULL, hInstance, NULL);
	HWND hWndParent2 = CreateWindow("win", "纯API创建窗口", WS_OVERLAPPEDWINDOW, 100, 100, 500, 500, NULL, NULL, hInstance, NULL);
	//第四部:显示
	ShowWindow(hWndParent, SW_SHOWNORMAL);
	ShowWindow(hWndParent2, SW_SHOWNORMAL);
	//更新窗口(发送WM_PAINT)
	UpdateWindow(hWndParent);
	UpdateWindow(hWndParent2);