Win32 编程 —— CreateWindow

Hello, 欢迎登录 or 注册!

/ 1评 / 0

本文作者:  本文分类:Win32编程 编程学习笔记  浏览:1286
阅读时间:3905字, 约4.5-6.5分钟

Hello大家好,欢迎回来,这里是nth.ink,今天我们继续讲Win32编程。

上一篇我们讲到,Win32有一个特点:一个个全部都是“窗口”。今天我们就围绕着“窗口”来展开。

CreateWindow

语法: CreateWindowA(lpClassName,lpWindowName,dwStyle,x,y,nWidth,nHeight,hWndParent,hMenu,hInstance,lpParam)

看不懂?很正常。win32您要是自学成才我拜您老师。我们就来详细解说一下。

lpClassName: 这个控件是什么类型的呢?这里应该填写一个字符串,是类名。一半常见的有“STATIC”(静态字符串),“EDIT”( 编辑框),“button”(按钮)等等。

lpWindowName: 这个控件里面(默认)写什么呢?(如果是新建的是一个“窗口”,那么就是它的标题栏里面的东西)

dwStyle: DWORD类型,就是叠加属性用的。如果是一个“窗口”就要WS_OVERLAPPEDWINDOW属性,如果是一个“控件”就要WS_CHILD属性。一般还要加上WS_VISIBLE(可见的)。如果需要,还有WS_BORDER(加上边框),WS_VSCROLL(竖直滚动),WS_HSCROLL(水平滚动)。如果是编辑框还可加上ES_MULTILINE(支持多行),ES_WANTRETURN等。如果是按钮还可以加上BS_AUTORADIOBUTTON(打勾的那个框)等。具体以后碰到了再讲。注意:属性之间使用位或运算符 | 连接。Win32编程基本上都是这样子叠加属性的。

x:如果是窗口的话就是它创建的位置(的横坐标)。如果是控件的话就是它放在窗口里的什么地方(的横坐标)。

y:如果是窗口的话就是它创建的位置(的横坐标)。如果是控件的话就是它放在窗口里的什么地方(的横坐标)。

nWidth:它有多宽?

nHeight:它有多高?

hWndParent:父窗口的“句柄”。如果是创建的一个窗口,填NULL即可。如果是创建的一个控件(相当于子窗口),就填父窗口的“句柄”。比如在我们示例代码中:

hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,"WindowClass","Hello, world!",WS_VISIBLE|WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, /* x */
		CW_USEDEFAULT, /* y */
		640, /* width */
		480, /* height */
		NULL,NULL,hInstance,NULL);

这是创建了一个窗口,所以填NULL。(这里用的是CreateWindowEx,因此可能语法稍有不同。但是对应CreateWindow的地方填的是NULL。在这里返回了创建好的窗口句柄(hwnd)。那么以后创建子窗口的时候就用hwnd。(顺便说一句:hwnd也是会作为参数传递到WndProc的,因此没有必要设置为全局变量。

LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)

所以只要用自带的hwnd即可。

hMenu:这个控件的编号是什么?(一般都是1001,1002,1003......这样子编的,从1001开始。为了形象一般都会定义成宏,如:

#define IDC_STATIC1 1001

这样。)注意要强制类型转换成HMENU。如:(HMENU)IDC_STATIC1。

hInstance:玄乎的东西。一般填NULL即可。

lParam:参数,一般填NULL即可。

那么下面就是一行示例:

CreateWindow("STATIC", "This is a text!", WS_CHILD|WS_VISIBLE|WS_BORDER, 30, 50, 200, 25, hwnd, (HMENU)IDC_STATIC1, NULL, NULL);

实践

好了我们试试看吧。

复制这些代码到您的Dev-C++新项目,然后尝试编译运行......

#include <windows.h>
#define IDC_STATIC1 1001 

LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) {
/* This is where all the input to the window goes to */
	switch(Message) {
		case WM_CREATE: {
			CreateWindow("STATIC", "This is a text!", WS_CHILD|WS_VISIBLE|WS_BORDER, 30, 50, 200, 25, hwnd, (HMENU)IDC_STATIC1, NULL, NULL);
			return 0;
		}
		/* Upon destruction, tell the main thread to stop */
		case WM_DESTROY: {
			PostQuitMessage(0);
			break;
		}
		
		/* All other messages (a lot of them) are processed using default procedures */
		default:
			return DefWindowProc(hwnd, Message, wParam, lParam);
	}
	return 0;
}

/* The 'main' function of Win32 GUI programs: this is where execution starts */
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
	WNDCLASSEX wc; /* A properties struct of our window */
	HWND hwnd; /* A 'HANDLE', hence the H, or a pointer to our window */
	MSG msg; /* A temporary location for all messages */

	/* zero out the struct and set the stuff we want to modify */
	memset(&wc,0,sizeof(wc));
	wc.cbSize		 = sizeof(WNDCLASSEX);
	wc.lpfnWndProc	 = WndProc; /* This is where we will send messages to */
	wc.hInstance	 = hInstance;
	wc.hCursor		 = LoadCursor(NULL, IDC_ARROW);
	
	/* White, COLOR_WINDOW is just a #define for a system color, try Ctrl+Clicking it */
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
	wc.lpszClassName = "WindowClass";
	wc.hIcon		 = LoadIcon(NULL, IDI_APPLICATION); /* Load a standard icon */
	wc.hIconSm		 = LoadIcon(NULL, IDI_APPLICATION); /* use the name "A" to use the project icon */

	if(!RegisterClassEx(&wc)) {
		MessageBox(NULL, "Window Registration Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
		return 0;
	}

	hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,"WindowClass","Hello, world!",WS_VISIBLE|WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, /* x */
		CW_USEDEFAULT, /* y */
		640, /* width */
		480, /* height */
		NULL,NULL,hInstance,NULL);

	if(hwnd == NULL) {
		MessageBox(NULL, "Window Creation Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
		return 0;
	}

	/*
		This is the heart of our program where all input is processed and 
		sent to WndProc. Note that GetMessage blocks code flow until it receives something, so
		this loop will not produce unreasonably high CPU usage
	*/
	while(GetMessage(&msg, NULL, 0, 0) > 0) { /* If no error is received... */
		TranslateMessage(&msg); /* Translate key codes to chars if present */
		DispatchMessage(&msg); /* Send it to WndProc */
	}
	return msg.wParam;
}

可以看到结果:

image-20200509105544170

如何?与您想的一样吗?

好了,本文就讲那么多。Win32的世界很大,有大量的内容等待我们去探索!我们已经讲了的只是冰山一角,之后我会继续更新!!!

(还有,可以发挥自己的想象,试试看BUTTON,EDIT等,这会让您很有收获的!自己多多摸索,才能成功。)

本文由nth.ink原创,转载请注明出处。

关于作者

  1. qyh说道:

    管理员文章免审核

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注