您的位置:首页 > 其它

如何创建一个win32程序

2015-11-13 14:25 639 查看
学过一段时间的c++,建立的都是win32 console application,我来介绍一下如何建立一个简单的win32程序,相比win32 console application,会有大家常见的窗口,更像程序一些。

首先要写类似于main函数的WinMain,

int WINAPI WinMain( HINSTANCE hinstance,

HINSTANCE hprevinstance,

LPSTR lpcmdline,

int ncmdshow)

WINAPI是干什么的呢?它是调用声明,相当于_stdcal。c++默认的调用声明是_cdecl。两者区别为:

_stdcal函数在结束后自己清栈,_cdecl由调用者(不是指人自己,指的是调用的程序)清栈。当函数参数个数可变的时候,只能_cdecl调用,在不知道个数的情况下,函数自己不知道怎么清栈;不同的编译器会按不同的方式堆栈,这样会使得如果使用_cdecl声明时,调用者不一定可以成功清栈。

(参考了http://blog.csdn.net/dengziliang001/article/details/17448789)

hinstance是Windows为应用程序产生的实例句柄,可以看成这个就是程序的地址,跟踪程序。

hprevinstance,现在已经不使用这个参数了。

lpcmdline,与main中的命令行差不多,基本写程序时不用管。

ncmdshow,带有如何打开主应用程序窗口的信息,比如最大化,最小化,一般用的多的是ShowWindow(),ncmd不怎么用。

函数体怎么写呢?看看下面:

WNDCLASSEX winclass; // this will hold the class we create

HWND hwnd;// generic window handle

MSG msg;// generic message

HDC hdc; // graphics device context

// first fill in the window class stucture

winclass.cbSize = sizeof(WNDCLASSEX);

winclass.style = CS_DBLCLKS | CS_OWNDC |

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(BLACK_BRUSH);

winclass.lpszMenuName = NULL;

winclass.lpszClassName = WINDOW_CLASS_NAME;

winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

WNDCLASSEX是一个类,因为你要创建一个窗口,然后在上面输入输出操作,WNDCLSSEX可以看成一个窗口类,而winclass可以看成实例(即变量),hwnd,msg,hdc在后面会讲到,首先要做的是填winclass的各个属性,后面的一大串全是设置属性,比较重要的是 winclass.style,它指出了窗口的重要属性,如窗口宽度变化后会重画,高度变化后会重画,剩下的参数查msdn就知道了。

然后你需要去注册这个类,

if (!RegisterClassEx(&winclass))

return(0);

外面的if,当没注册成功就返回0,防止程序没注册成功,往下运行出现未知的错误。

然后就是创建一个窗口,

if (!(hwnd = CreateWindowEx(NULL, // extended style

WINDOW_CLASS_NAME, // class

"Demo", // title

WS_OVERLAPPEDWINDOW | WS_VISIBLE,

0,0, // initial x,y

500,400, // initial width, height

NULL,
// handle to parent

NULL,
// handle to menu

hinstance,// instance of this application

NULL)))
// extra creation parms

return(0);

CreateWindowEx()会返回一个指向窗口的的句柄,相当于它的地址。

上面的一系列都可以直接复制张贴,根据需要,改一改属性即可,然后我一般会编一个循环,去处理消息。

while(TRUE)

{

if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

} // end if

} // end while

return(msg.wParam);

}

其中 if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

理解成先判断有没有消息,有的话就传递给相应的程序处理,消息可以使单击鼠标左键,关闭窗口等。

之后return,就写好主函数。

除了主函数还需要写一个消息处理函数,每个窗口都有一个窗口处理函数,而关联两者,就是在设置窗口属性时的winclass.lpfnWndProc= WindowProc,WindowProc是处理函数的名字,当窗口有相应的消息的时候,就会调用处理函数处理.下面是一个窗口处理函数:

LRESULT CALLBACK WindowProc(HWND hwnd,

UINT msg,

WPARAM wparam,

LPARAM lparam)

{

PAINTSTRUCT ps;

switch(msg){

case WM_CREATE:

{

} break;

case WM_PAINT:

{

BeginPaint(hwnd,&ps);

EndPaint(hwnd,&ps);

return(0);

} break;

case WM_DESTROY:

{

PostQuitMessage(0);

return(0);

} break;

default:break;

}

return (DefWindowProc(hwnd, msg, wparam, lparam));

}

首先看一下函数的参数,hwnd 是调用窗口的句柄,便于对窗口操作,msg有消息类型的信息,wparam,lparam包含具体消息的细节。

总之其实上面的都可以直接复制张贴,至于该怎么操作只需要改一下处理函数,还有在while循环里做些填充。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: