C++创建Windows窗体流程(全网最全)

6,094 阅读5分钟

Windows创建窗体过程(C++)

1.创建窗体类

窗口类 WNDCLASSEX 说明

结构体形式:

typedef struct tagWNDCLASSEXW {
    UINT        cbSize;
    /* Win 3.x */
    UINT        style;
    WNDPROC     lpfnWndProc;
    int         cbClsExtra;
    int         cbWndExtra;
    HINSTANCE   hInstance;
    HICON       hIcon;
    HCURSOR     hCursor;
    HBRUSH      hbrBackground;
    LPCWSTR     lpszMenuName;
    LPCWSTR     lpszClassName;
    /* Win 4.0 */
    HICON       hIconSm;
} 

参数解释:

cbSize:设置WNDCLASSEX类的大小 直接用sizeof(WNDCLASSEX)即可

style: 窗口类的样式 :可以同时设置多个 以|划分

包括如下样式及说明:

/*
 * Class styles
 */
#define CS_VREDRAW          0x0001  //高度改变时,重绘窗体
#define CS_HREDRAW          0x0002  //宽度改变时,重绘窗口
#define CS_DBLCLKS          0x0008  //双击窗口时,发送鼠标双击消息
#define CS_OWNDC            0x0020  //为窗体类创建唯一的设备上下文
#define CS_CLASSDC          0x0040
#define CS_PARENTDC         0x0080  //使子窗口可以在父窗口上绘图
#define CS_NOCLOSE          0x0200   //设置关闭按钮不可见
#define CS_SAVEBITS         0x0800
#define CS_BYTEALIGNCLIENT  0x1000
#define CS_BYTEALIGNWINDOW  0x2000
#define CS_GLOBALCLASS      0x4000

#define CS_IME              0x00010000
#if(_WIN32_WINNT >= 0x0501)
#define CS_DROPSHADOW       0x00020000
#endif /* _WIN32_WINNT >= 0x0501 */

lpfnWndProc:窗体消息的回调处理函数 重点 :用于处理Windows窗体各类消息,是Windows的灵魂

cbClsExtra:windows程序为每一个窗口设计类管理一个WNDCLASS结构。在应用程序注册一个窗口类的时候,可以让windows分配一定字节空间的内存,这部分内存成为类的附件内存,有属于这个窗口类的所有窗口共享,类附件内存信息用于存储窗口类的附加信息。windows系统将这部分内存初始化为0,因此我们经常设置此参数为0.

cbWndExtra:windows程序为每一个窗口管理一个内部数据结构,在注册窗口类的时候,系统可以为每一个窗口分配一定的字节数的附加内存空间,称为窗口附件内存。应用程序可使用这部分内存存储窗口特有的数据,windows系统把这部分内存初始化为0.

hInstance:窗体所在的句柄

hIcon: 窗体程序图标的句柄

图标资源示例:

#define IDI_APPLICATION     MAKEINTRESOURCE(32512)
#define IDI_HAND            MAKEINTRESOURCE(32513)
#define IDI_QUESTION        MAKEINTRESOURCE(32514)
#define IDI_EXCLAMATION     MAKEINTRESOURCE(32515)
#define IDI_ASTERISK        MAKEINTRESOURCE(32516)

hCursor:鼠标样式

鼠标样式包括:

#define IDC_ARROW           MAKEINTRESOURCE(32512)
#define IDC_IBEAM           MAKEINTRESOURCE(32513)
#define IDC_WAIT            MAKEINTRESOURCE(32514)
#define IDC_CROSS           MAKEINTRESOURCE(32515)
#define IDC_UPARROW         MAKEINTRESOURCE(32516)
#define IDC_SIZE            MAKEINTRESOURCE(32640)  /* OBSOLETE: use IDC_SIZEALL */
#define IDC_ICON            MAKEINTRESOURCE(32641)  /* OBSOLETE: use IDC_ARROW */
#define IDC_SIZENWSE        MAKEINTRESOURCE(32642)
#define IDC_SIZENESW        MAKEINTRESOURCE(32643)
#define IDC_SIZEWE          MAKEINTRESOURCE(32644)
#define IDC_SIZENS          MAKEINTRESOURCE(32645)
#define IDC_SIZEALL         MAKEINTRESOURCE(32646)
#define IDC_NO              MAKEINTRESOURCE(32648) /*not in win3.1 */
#if(WINVER >= 0x0500)
#define IDC_HAND            MAKEINTRESOURCE(32649)
#endif /* WINVER >= 0x0500 */
#define IDC_APPSTARTING     MAKEINTRESOURCE(32650) /*not in win3.1 */
#if(WINVER >= 0x0400)
#define IDC_HELP            MAKEINTRESOURCE(32651)
#endif /* WINVER >= 0x0400 */

hbrBackground:客户区颜色,即在导航栏下方的color

lpszMenuName:菜单名字

lpszClassName:类名(必须添加)

hIconSm:窗口标题栏图标

创建窗体代码示例:

//1.定义当前窗口类  WNDCLASSEX
WNDCLASSEX wclass;
wclass.cbSize = sizeof(WNDCLASSEX);
wclass.style = CS_VREDRAW|CS_HREDRAW|CS_NOCLOSE;
wclass.lpfnWndProc = MSGPROCFUN;
wclass.cbClsExtra = 0;
wclass.cbWndExtra = 0;
wclass.hInstance = hInstance;
wclass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
wclass.hCursor = LoadCursor(NULL,IDC_ARROW);
wclass.hbrBackground = (HBRUSH)(COLOR_WINDOW +2);
wclass.lpszMenuName = L"MENU";
wclass.lpszClassName = WNDCLASSNAME;
wclass.hIconSm=LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));

2.注册窗体类

调用WindowsAPI RegisterClassEx( __in CONST WNDCLASSEXW )

示例代码:

RegisterClassEx(&wclass);

3.创建窗体

调用WindowsAPICreateWindowW(lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam)

参数说明:

lpClassName:对应窗口类名 相当于绑定窗口类名

lpWindowName: 窗口显示的名字

dwStyle:窗口类型

x:windows桌面的x位置

y:windows桌面的y位置

nWidth:窗体的宽度

nHeight:窗体的高度

hWndParent:父窗体的句柄

hMenu:主菜单的句柄

hInstance:窗体句柄

lpParam:传给窗体的参数

返回值:HWND 当前创建成功窗体的句柄

示例代码:

HWND hWnd = CreateWindow(WNDCLASSNAME,WINDOWNAME,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,600,700,NULL,NULL,hInstance,NULL);

4.显示窗体和更新窗体

调用API ShowWindow(hwnd,ncmdshow)UpdateWindow(hwnd)

示例代码:

ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);

5.初始化窗体消息模块

示例代码如下:

	MSG msg; 
	while (GetMessage(&msg, NULL, 0, 0)) { 
		TranslateMessage(&msg); //翻译消息
		DispatchMessage(&msg);  //派遣消息
	} 
	return (int) msg.wParam;

6.响应消息函数处理

//处理消息
LRESULT CALLBACK MSGPROCFUN(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	PAINTSTRUCT ps;  
	HDC hdc;   
	TCHAR greeting[] = _T("Hello, World!");   
	switch (message) {   
	case WM_PAINT:   
		hdc = BeginPaint(hWnd, &ps);   
		// -----------------在这段代码对应用程序进行布局------------------------   
		// 对于此应用程序,开始调用和结束调用之间的逻辑是在窗口中显示字符串 “Hello,World!”。  
		// 请注意 TextOut 函数用于显示字符串。  
		TextOut(hdc, 50, 5, greeting, _tcslen(greeting));   
		EndPaint(hWnd, &ps);  
		break;   
	case WM_DESTROY:   
		PostQuitMessage(0);   
		break;  
	default:   
		//DefWindowProc缺省窗口处理函数  
		//这个函数是默认的窗口处理函数,我们可以把不关心的消息都丢给它来处理  
		return DefWindowProc(hWnd, message, wParam, lParam);   
		break;   
	}   
	return 0;   
}

完整的代码:

// Calculate.cpp : 定义应用程序的入口点。
//

#include "stdafx.h"
#include "Calculate.h"

using namespace std;


HINSTANCE hCurInstance; //当前窗口句柄

// 主窗体类名  
static TCHAR szWindowClass[] = _T("win32app");   

//设置回调函数,用于处理windows窗体的消息
LRESULT CALLBACK MSGPROCFUN(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
	//1.定义当前窗口类  WNDCLASSEX
	WNDCLASSEX wclass;
	wclass.cbSize = sizeof(WNDCLASSEX);
	wclass.style = CS_HREDRAW | CS_VREDRAW |CS_NOCLOSE;   
	wclass.lpfnWndProc = MSGPROCFUN;
	wclass.cbClsExtra = 0;
	wclass.cbWndExtra = 0;
	wclass.hInstance = hInstance;
	wclass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
	wclass.hCursor = LoadCursor(NULL,IDC_ARROW);
	wclass.hbrBackground = (HBRUSH)(COLOR_WINDOW +1);
	wclass.lpszMenuName =NULL;
	wclass.lpszClassName = szWindowClass;
	wclass.hIconSm=LoadIcon(wclass.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
    hCurInstance = hInstance;
	//2.注册窗体类
	RegisterClassEx(&wclass);

	//3.创建窗体
	HWND hWnd = CreateWindow(szWindowClass,szWindowClass,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,600,700,NULL,NULL, hInstance ,NULL);

	//4.显示窗体 和 更新窗体 
	ShowWindow(hWnd,nCmdShow);
	UpdateWindow(hWnd);

	//初始化窗体消息模块
	MSG msg; 
	while (GetMessage(&msg, NULL, 0, 0)) { 
		TranslateMessage(&msg); //翻译消息
		DispatchMessage(&msg);  //派遣消息
	} 
	return (int) msg.wParam;
}

//处理消息
LRESULT CALLBACK MSGPROCFUN(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	PAINTSTRUCT ps;  
	HDC hdc;   
	TCHAR greeting[] = _T("Hello, World!");   
	switch (message) {   
	case WM_PAINT:   
		hdc = BeginPaint(hWnd, &ps);   
		// -----------------在这段代码对应用程序进行布局------------------------   
		// 对于此应用程序,开始调用和结束调用之间的逻辑是在窗口中显示字符串 “Hello,World!”。  
		// 请注意 TextOut 函数用于显示字符串。  
		TextOut(hdc, 50, 5, greeting, _tcslen(greeting));   
		EndPaint(hWnd, &ps);  
		break;   
	case WM_DESTROY:   
		PostQuitMessage(0);   
		break;  
	default:   
		//DefWindowProc缺省窗口处理函数  
		//这个函数是默认的窗口处理函数,我们可以把不关心的消息都丢给它来处理  
		return DefWindowProc(hWnd, message, wParam, lParam);   
		break;   
	}   
	return 0;   
}

运行截图: