学习win32 API开发7-在窗口中使用控件

一、

我知道用VB写程序就是直接托控件的,MFC也是托控件的,那win32 API编程怎么实现那样的控件呢?嘿嘿,现在学到了。

创建控件就用CreateWindow函数实现。CreateWindow函数有一个参数是HWND,就是父窗口的句柄,这么说来就可以有子窗口了嘛。还有第1个参数是窗口类型,利用这个参数就可以创建不同的控件了,比如:按钮(BUTTON),编辑框(edit),文本框等。

CreateWindow("Button","退出",WS_VISIBLE|WS_CHILD,10,10, 50,30, hwnd,NULL,hInstance,NULL);

WS_VISIBLE是可见,就是可以在窗口上面显示出来吧,WS_CHILD是说这个窗口是个子窗口,hwnd是父窗口的句柄了。就这么一句就可以看到一个长50,宽30的按钮了。

但是,现在一个问题是,这个函数要写在哪里呢?我试了2个地方,第一个地方就是父窗口创建完后,紧接着就创建这个按钮。第二个地方嘛,就在消息处理函数里面了。

父窗口创建完后会有一个WM_CREATE消息,那现在这个按钮就可以写在这个消息的处理里面了。

case WM_CREATE:

//CreateWindow(TEXT("Button"),TEXT("退出"),WS_VISIBLE|WS_CHILD,10,10, 50,30, hwnd,,hg_app,NULL);

但是这样的话有个问提,就是倒数第二个参数,窗口实例句柄(什么是窗口实例句柄,我还不太明白,额...),这个参数写什么呢?试一下吧,就写父窗口的那个hInstance吧,那就需要定义一个全局变量了,嗯,就定义一个:HINSTANCE hg_app;

那现在就给它赋值,就在WinMain函数里面吧,我这里就写在父窗口创建完后吧!hg_app = hInstance;

额...貌似完成了,运行下,发现那个按钮出现了。

但是呢,现在点击这个按钮是没有作用的,因为还没有给它写上代码做啥事情,那就写一个吧!

这个按钮控件,按下去了会发送一个WM_COMMAND消息,但是知道了是这个消息,那怎么是知道是这个按钮呢(如果有很多的按钮)?所以它也应该有个ID吧!但是创建控件的时候没有ID这个项呀!

原来,它和菜单一样啊,菜单的ID是怎么获取得到的?LOWORD(wparam)就是这个,是在消息处理函数里面的wparam参数里面取来的。LOWOR就是一个宏,就是转换为WORD类型的,WORD类型就是unsigned short。因为菜单的ID是在wparam这个参数的低位存放的。

那这个控件的ID也跟菜单一样写就是了,菜单的ID是写在哪里的?我创建菜单是用资源文件生成的,那我就不知道这个控件的ID写在哪里了。不过,总算还是从别的地方知道了,CreateWindow函数有个参数是指定菜单的,那这个控件是没有菜单的,那就用这个菜单当作ID了,我就给他取一个ID名字叫做IDC_BUTTON吧:

CreateWindow("Button","退出",WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON,10,10, 50,30, hwnd,(HMENU)IDC_BUTTON,hInstance,NULL);

现在IDC_BUTTON是个没有定义的,先看看菜单,每项的定义都是在头文件resource.h中,那这里我就在程序的头部定义吧:

#define  IDC_BUTTON                        40004

那现在就响应这个按钮吧!

case IDC_BUTTON:
MessageBox(hwnd,"程序将退出","提示",MB_OK|MB_ICONQUESTION);
PostQuitMessage(0);//终止程序

下面看看完整程序:

#include "Windows.h"
#include "resource.h"

#define IDC_BUTTON                        40004

void ShowErrMsg() 
{ 
    //TCHAR szBuf[80]; 
    LPVOID lpMsgBuf;
    DWORD dw = GetLastError(); 
    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
        NULL,
        dw,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR) &lpMsgBuf,
        0, NULL );

    MessageBox(NULL, (LPTSTR)lpMsgBuf, "系统错误", MB_OK|MB_ICONSTOP); 
		//OutputDebugString();
    LocalFree(lpMsgBuf);
}

LRESULT CALLBACK WinProc(HWND hwnd,UINT umsg,WPARAM wparam,LPARAM lparam);
HINSTANCE hg_app;
int WINAPI WinMain(HINSTANCE hInstance,
				   HINSTANCE hPrecInstance,
				   LPSTR lpCmdLine,
				   int nShowCmd
				   )
{
	TCHAR* clsName="myclass";
	WNDCLASS mwc={sizeof(WNDCLASS)};

	//设计窗口类
	mwc.lpfnWndProc = WinProc;	//窗口处理函数
	mwc.hbrBackground = (HBRUSH)COLOR_WINDOW;	//窗口背景色
	mwc.lpszClassName = clsName;	// 窗口类名
	mwc.style = CS_HREDRAW | CS_VREDRAW;	//窗口类型
	mwc.cbClsExtra = 0;	//窗口扩展
	mwc.cbWndExtra = 0;	//窗口实例扩展
	mwc.lpszMenuName = MAKEINTRESOURCE(IDR_MENUmain);	//窗口菜单
	//mwc.lpszMenuName = (CHAR *)IDR_MENUmain;
	mwc.hInstance = hInstance;	//实例句柄

	//注册窗口类
	RegisterClass(&mwc);

	//创建窗口
	HWND hwnd = CreateWindow(
		clsName,	//类名,就是刚才注册的
		//"HEHE",
		TEXT("Windows的标题"),	//窗口标题
		WS_SYSMENU|WS_MINIMIZEBOX|WS_MAXIMIZEBOX,	//外观样式
		400,	//相对于父窗口的X坐标
		150,	//相对于父窗口的Y坐标
		400,	//窗口的宽
		400,	//窗口的高
		NULL,	//父窗口,没有就写NULL
		0,
		//LoadMenu(hInstance,MAKEINTRESOURCE(IDR_MENUmain)),	//窗口菜单,也没有,写NULL
		hInstance,	//当前应用程序的实例句柄
		NULL);	//附加数据,没有,为NULL
	if( hwnd == NULL)	//检查窗口是否创建成功
	{
		ShowErrMsg();
		//DWORD err = GetLastError();
		//TCHAR  er[123] ;
		//wsprintf(er,"%i",err);
		//MessageBox(NULL,er,TEXT("提示"),MB_ICONWARNING);
		
		MessageBox(NULL,TEXT("创建窗口失败"),TEXT("提示"),MB_ICONWARNING);
		return 0;
	}
	//显示窗口和更新窗口
	ShowWindow(hwnd,SW_SHOW);
	UpdateWindow(hwnd);

	CreateWindow("Button","退出",WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON,10,	10,	50,	30,	hwnd,(HMENU)IDC_BUTTON,	hInstance,NULL);

	hg_app = hInstance;
	//消息循环
	MSG msg;
	while(GetMessage(&msg,NULL,0,0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	//MessageBox(NULL,TEXT("你好 Windows 世界^_^"),TEXT("标题"),MB_OK);
	return 0;
}

LRESULT CALLBACK WinProc(HWND hwnd,UINT umsg,WPARAM wparam,LPARAM lparam)
{
	switch(umsg)
	{
	case WM_PAINT:
		{
			PAINTSTRUCT ps;
			BeginPaint(hwnd,&ps);
			DrawText(ps.hdc,TEXT("你好啊"),6,&(ps.rcPaint),DT_CENTER);
			EndPaint(hwnd,&ps);
		}
		return 0;
	case WM_CREATE:
		//CreateWindow(TEXT("Button"),TEXT("退出"),WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON,	10,	10,	50,	30,	hwnd,(HMENU)IDC_BUTTON,hg_app,NULL);
		return 0;
	case WM_COMMAND:
		{
			HMENU hm=GetMenu(hwnd);			//获取菜单句柄
			HMENU hsm = GetSubMenu(hm,1);	//获取菜单下级的菜单句柄
			
			switch(LOWORD(wparam))
			{
			case IDM_EXIIT:	PostQuitMessage(0);
				break;
			case IDM_ABOUT: 
				CheckMenuItem(hm,IDM_ABOUT,MF_CHECKED);	//选中
				break;
			case IDM_HELP:
				CheckMenuRadioItem(hsm,IDM_ABOUT,IDM_HELP,IDM_HELP,MF_BYCOMMAND);	//单选项
				break;
			case IDC_BUTTON:
				MessageBox(hwnd,"程序将退出","提示",MB_OK|MB_ICONQUESTION);
				PostQuitMessage(0);	//终止程序
				break;
			default:
				break;
			}
		}
		return 0;
	case WM_DESTROY:
		{
			PostQuitMessage(0);	//终止程序
			return 0;
		}
	}
	return DefWindowProc(hwnd,umsg,wparam,lparam);
}

学习win32 API开发7-在窗口中使用控件_第1张图片

看到了,按下“退出”按钮就提示这么个消息!

二、

现在可以试着改下风格,创建一个编辑框把,能够输入文字的。

就是修改下CreateWindow函数的第一个参数,就可以了:

CreateWindow("edit","退出",WS_VISIBLE|WS_CHILD|BS_AUTORADIOBUTTON ,10, 10, 150, 30, hwnd,(HMENU)IDC_BUTTON, hInstance,NULL);

这样就可以看到一个文本框了。

学习win32 API开发7-在窗口中使用控件_第2张图片

还有其他更多的,日后慢慢学习。

你可能感兴趣的:(windows开发)