heisehuoyan

导航

<2006年7月>
2526272829301
2345678
9101112131415
16171819202122
23242526272829
303112345

统计

常用链接

留言簿(3)

随笔档案

文章档案

搜索

最新评论

阅读排行榜

评论排行榜

VC++中如何创建一个窗口

首先要谈论一点C++的知识,因为要想建立一个窗口,你就得先建立一个窗口类。窗口类包含所有的有关窗口的信息,如用什么样的鼠标符号,菜单样式等等。开发任何一个窗口程序,都离不开窗口类的建立。为了达到此目的,你必须填写WNDCLASSEX结构。EX的意思是“扩充”的意思,因为有一个老的结构叫作WNDCLASS,这里,我们将使用WNDCLASSEX结构,它的样子如下:

 

typedef struct _WNDCLASSEX {
        UINT cbSize;
        UINT style;
        WNDPROC lpfnWndProc;
        int cbClsExtra;
        int cbWndExtra;
        HANDLE hInstance;
        HICON hIcon;
        HCURSOR hCursor;
        HBRUSH hbrBackground;
        LPCTSTR lpszMenuName;
        LPCTSTR lpszClassName;
        HICON hIconSm;
} WNDCLASSEX;
 

这个结构有不少成员,讨厌的是,你必须为窗口类设置每一个成员。莫发愁,纸老虎一个。让我们来个速成。

※ UINT cbSize:指定了以字节为单位的结构的大小。这个成员是通过sizeof(WNDCLASSEX)实现的。你将会经常看到它,尤其是你使用了DirectX。

※ UINT style:指定了窗口的风格。它经常被以CS_打头的符号常量定义。两种或两种以上的风格可以通过C语言中的“或”(|)运算符加以组合。大多数情况我们只应用四种风格,出于对文章长度的考虑,我们只列出这四种。若你还需要其它的,到MSDN里找一下好了。当然前提是你使用的是Visual C++。

◎ CS_HREDRAW:一旦移动或尺寸调整使客户区的宽度发生变化,就重新绘制窗口。

◎ CS_VREDRAW:一旦移动或尺寸调整使客户区的高度发生变化,就重新绘制窗口。

◎ CS_OWNDC:为该类中的每一个窗口分配一个唯一的设备上下文。

◎ CS_DBLCLKS:当用户双击鼠标时向窗口过程发送双击消息。

※ WNDPROC lpfnWndProc:是指向窗口过程的指针。一般都指向CALLBACK函数。如果你没有用过函数指针,简单理解为函数的地址就是函数的名字,名字后面别带括号。

※ int cbClsExtra:它是为类保留的额外信息 。大多数程序员不用它,你在在写游戏程序时也不太可能用它,所以,设为0好了。

※ int cbWndExtra:同上一个差不多,设为0好了。

※ HANDLE hInstance:是指向窗口过程实例的句柄。同时也是WinMain()函数的参数之一。应该设置为hinstance。

※ HICON hIcon:指向窗口图标的句柄,它通常被LoadIcon()函数设置。在你学会如何在你的程序中使用资源前,你先设置成如下样子:LoadIcon(NULL,IDI_WINLOGO)。当然,还有一些其它的IDI_打头的符号常量,可以自己去帮助文件里寻找。

※ HCURSOR hCursor:指向窗口光标的句柄,它通常被LoadCursor()函数设置,在你学会如何在你的程序中使用资源前,你先用Windows默认的吧,LoadCursor(NULL,IDC_ARROW)。

※ HBRUSH hbrBackground:当你的窗口过程得到消息,要求刷新(或重画)窗口时,至少要用一种纯色或“brush”(画刷)重画窗口区域,画刷是由参数确定的。你可以使用GetStockObject()函数调用几种常备的画刷,如BLACK_BRUSH, WHITE_BRUSH, GRAY_BRUSH等。现在,你就用GetStockObject(BLACK_BRUSH)吧。也许你觉得我说的太简单了,是因为不想把开始弄得太复杂。在以后的篇幅里会详细讲述的。

※ LPCTSTR lpszMenuName:如果你想建立一个有下拉菜单的窗口,你得给这个参数赋一个菜单名称(这涉及到资源),由于你还不知道怎么创建菜单,你就先用NULL设置成一个没有菜单的窗口吧。

※ LPCSTR lpszClassName:很显然,你需要给类起个名字,随你便,如“**”。要用双引号引上。

※ HICON hIconSm:指向小图标的句柄。小图标用来显示在窗口的标题栏里。要用到LoadIcon()函数,现在,先用Windows默认的吧,LoadIcon(NULL,IDI_WINLOGO)。

好了,现在你关于WNDCLASSEX结构知道的已经差不多了,你可以自己设置它了。下面是一个例子:


WNDCLASSEX sampleClass; // declare structure variable
sampleClass.cbSize = sizeof(WNDCLASSEX); // always use this!
sampleClass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW; // standard settings
sampleClass.lpfnWndProc = MsgHandler; // we need to write this!
sampleClass.cbClsExtra = 0; // extra class info, not used
sampleClass.cbWndExtra = 0; // extra window info, not used
sampleClass.hInstance = hinstance; // parameter passed to WinMain()
sampleClass.hIcon = LoadIcon(NULL, IDI_WINLOGO); // Windows logo
sampleClass.hCursor = LoadCursor(NULL, IDC_ARROW); // standard cursor
sampleClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); // a simple black brush
sampleClass.lpszMenuName = NULL; // no menu
sampleClass.lpszClassName = "Sample Class" // class name
sampleClass.hIconSm = LoadIcon(NULL, IDI_WINLOGO); // Windows logo again
 

我想,现在你已经有点儿不太崇拜Windows程序员了吧。言归正传,有一点我得提醒你,注意函数GetStockObject()前的(HBRUSH)类型配置,这是因为GetStockObject()可以调用其它的对象,不仅仅是“brush”,所以你需要一个HBRUSH类型配置。在Visual C++旧版本里不用配置,但新的6.0版本需要它,否则会编译出错。

下一件事是注册这个窗口类,只有这样,你才能创建新的窗口。十分简单,你只需要调用一个RegisterClassEX()函数,它只有一个参数,就是你的窗口类的地址(名字),根据我上面给的例子,这里应该这样:


RegisterClassEx(&sampleClass);
 

我们的窗口类创建完了,我们可以用它创建一个窗口了。

posted on 2006-07-27 17:48 黑色火焰 阅读(5678) 评论(2)  编辑 收藏 引用

评论

# re: VC++中如何创建一个窗口 2007-09-21 13:49

// 321.cpp : Defines the entry point for the application.
//
//帮我看下这段代码,为什么还不能生成

#include "stdafx.h"

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{ LRESULT CALLBACK WindowProc(HWND hwnd,
UINT msg,
WPARAM wParam,
LPARAM lParam
)
{
HPEN RedPen;
switch(msg)
{
case WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint(hwnd,&ps);
RedPen=CreatePen(PS_SOLID,5,RGB(255,0,0));
EndPaint(hwnd,&ps);
return 0;
}
}
}


WNDCLASSEX winclass;
winclass.cbSize=sizeof(WNDCLASSEX);
winclass.style=CS_HREDRAW | CS_VREDRAW;
winclass.lpfnWndProc =WindowProc;
winclass.cbClsExtra=0;
winclass.cbWndExtra=0;
winclass.hInstance=hInstance;
winclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
winclass.hCursor=LoadCursor(NULL,IDC_ARROW);
winclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
winclass.lpszMenuName=NULL;
winclass.lpszClassName="g_szWindowClassName";
winclass.hIconSm=LoadIcon(NULL,IDI_APPLICATION);
if(!RegisterClassEx(&winclass))
{MessageBox(NULL,"Class Registration Failed!","Error",0);
return 0;
}


HWND hWnd;
hWnd=CreateWindowEx(NULL,
"fuck",
"haah",
WS_OVERLAPPEDWINDOW,
0,
0,
20,
20,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);
MSG msg;
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);

}
// TODO: Place code here.

return 0;
}






  回复  更多评论   

# re: VC++中如何创建一个窗口 2007-09-23 16:42 郭玉臻


建立窗口建议在主程序的WM_CREATE消息中来做  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理