您的位置:首页 > 其它

用VC写的第一个窗口程序 Hello World!

2006-11-19 19:57 369 查看
作者:zieckey(zieckey@yahoo.com.cn)
All Rights Reserved!

最近学习VC编程,看了些书之后,发现原来也没有想象中的那么难。

现在将我的这一学习过程记录下了,以便我将来翻阅方便,同时也希望能给初学者一点借鉴。

Windows系统是一个消息驱动的OS,那么什么是消息呢?我很难说得清楚,也很难下一个定义,
我下面从不同的几个方面讲解一下,希望大家看了后有一点了解。
比如说你按下了一个按键,那么这个按键的动作在这一过程中就会产生一个消息,
OS就会将这个消息捕捉到,同时唤醒一个响应程序去处理这个消息。

操作系统将每个事件都包装成一个称为消息的结构体MSG来传递给应用程序,
参看MSDN,MSG结构定义如下:
typedef struct tagMSG {
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
DWORD time;
POINT pt;
} MSG;

我们知道,普通的C/C++程序的程序入口是 main 函数,那么VC下的窗口应用程序的入口函数是否也是的呢?
不是的,VC下的窗口应用程序的入口函数是 WinMain 函数。参考 MSDN,其定义如下:
int WINAPI WinMain(
HINSTANCE hInstance, // handle to current instance
HINSTANCE hPrevInstance, // handle to previous instance
LPSTR lpCmdLine, // command line
int nCmdShow // show state
);

那么怎么创建一个窗口应用程序呢?
创建一个完整的窗口需要经过下面四个操作步骤:
1. 设计一个窗口类;
2. 注册窗口类;
3. 创建窗口;
4. 显示及更新窗口。

好的,现在我们来看一个实例。

新建一个 Win32 Application 的空白工程,然后新建一个 C++ Source File 的cpp文件
该文件内容如下:

// name: winmain.cpp
// This is 1st program to study VC++.
// Author : zieckey All rights reserved.
// data : 2006/11/18

#include <windows.h>
#include <stdio.h>

LRESULT CALLBACK WinZieckeyProc( //CALLBACK是一种标准的函数调用约定,参数传递和堆栈清除的顺序
HWND hwnd , // handle to window
UINT uMsg , // message identifier
WPARAM wParam , // first message parameter
LPARAM lParam // second message parameter
) ;

int WINAPI WinMain(
HINSTANCE hInstance , // handle to current instance
HINSTANCE hPrevInstance , // handle to previous instance
LPSTR lpCmdLine , // command line
int nCmdShow // show state
)
{
WNDCLASS wndcls; // 1. 声明一个窗口类

wndcls.cbClsExtra = 0 ;
wndcls.cbWndExtra = 0 ;
wndcls.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH ) ;
wndcls.hCursor = LoadCursor( NULL , IDC_CROSS ) ;
wndcls.hIcon = LoadIcon( NULL , IDI_APPLICATION ) ;
wndcls.hInstance = hInstance;
wndcls.lpfnWndProc = WinZieckeyProc; //消息处理函数
wndcls.lpszClassName = "Zieckey_W";
wndcls.lpszMenuName = NULL;
wndcls.style = CS_HREDRAW | CS_VREDRAW ;

RegisterClass( &wndcls ) ; // 2. 注册这个窗口类

HWND hwnd; // 3. 创建窗口
hwnd = CreateWindow("Zieckey_W","zieckey@yahoo.com.cn",WS_OVERLAPPEDWINDOW,
200,100,640,480,NULL,NULL,hInstance,NULL) ;

ShowWindow( hwnd , SW_SHOWNORMAL ) ; // 4. 显示及更新窗口
// UpdateWindow(hwnd) ;

//消息处理
MSG msg;
while( GetMessage( &msg , NULL , 0 , 0 ) )
{
TranslateMessage( &msg ) ;
DispatchMessage( &msg ) ;
}
return 0;
}

LRESULT CALLBACK WinZieckeyProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
switch( uMsg )
{
case WM_CHAR: //按键的消息,消息值即为所按下的键值存储在wParam中
char szChar[20];
sprintf( szChar , "char is %c" , wParam ) ;
MessageBox( hwnd , szChar , "Message Box Showing Key" , 0) ;
break;
case WM_LBUTTONDOWN:
MessageBox(hwnd , "Left Mouse Clicked" , "Mouse Clicking" , 0) ;
HDC hdc; //设备驱动程序
hdc=GetDC(hwnd) ; //获得一个绘图设备,GetDC ReleaseDC 成对出现,而且不能在响应 WM_PAINT 消息的时候使用
TextOut(hdc , 0 , 100 , "This is your first windows program ! Enjoying yourself!" , strlen("This is your first windows program ! Enjoying yourself!")) ;
ReleaseDC(hwnd , hdc) ; //释放这个设备
break;
case WM_RBUTTONDOWN:
MessageBox(hwnd , "Right Mouse Clicked" , "Mouse Clicking" , 0) ;
HDC hdc2; //设备驱动程序
hdc2=GetDC(hwnd) ; //获得一个绘图设备
TextOut(hdc2 , 0 , 200 , "This is your first windows program ! Enjoying yourself!" , strlen("This is your first windows program ! Enjoying yourself!")) ;
ReleaseDC(hwnd , hdc2) ; //释放这个设备
break;
case WM_PAINT: //窗口重绘的时候就会发出这个消息 WM_PAINT
HDC hDC;
PAINTSTRUCT ps; //BeginPaint EndPaint 成对出现 ,而且只能在响应 WM_PAINT 消息的时候使用
hDC=BeginPaint(hwnd , &ps) ; //开始绘图,即绘制窗口
TextOut(hDC , 0 , 0 , "Hello World!" , strlen("Hello World!")) ;
EndPaint(hwnd , &ps) ; //释放HDC,结束绘图
break;
case WM_CLOSE:
if( IDYES == MessageBox(hwnd , "是否真的要退出" , "关闭窗口确认" , MB_YESNO) )
{
DestroyWindow(hwnd) ; //这里仅仅将窗口销毁,但是程序没有退出
}
break;
case WM_DESTROY:
PostQuitMessage( 0 ) ;
break;
default:
return DefWindowProc(hwnd , uMsg , wParam , lParam) ; //对不感兴趣的消息作一个缺省处理
}
return 0 ;
}

编译,运行,看看键盘、鼠标的响应效果怎么样?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: