WIN32简单的窗体代码,带函数功能注释

// 一个简单的Win32应用程序

// 通过这个简单的实例讲解Windows消息是如何传递的

#include 
" stdafx.h "
#include 
< windows.h >

// 声明窗口过程函数
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);

// 定义一个全局变量,作为窗口类名
TCHAR szClassName[]  =  TEXT( " SimpleWin32 " );

// 应用程序主函数
int  WINAPI WinMain (HINSTANCE hInstance,
                                  HINSTANCE hPrevInstance,
                                  LPSTR szCmdLine,
                                  
int  iCmdShow)
{

    
// 窗口类
    WNDCLASS wndclass;

    
// 当窗口水平方向的宽度和垂直方向的高度变化时重绘整个窗口
    wndclass.style  =  CS_HREDRAW | CS_VREDRAW;

    
// 关联窗口过程函数
    wndclass.lpfnWndProc  =  WndProc;
    wndclass.cbClsExtra 
=   0 ;
    wndclass.cbWndExtra 
=   0 ;
    wndclass.hInstance 
=  hInstance; // 实例句柄
    wndclass.hIcon  =  LoadIcon(NULL,IDI_APPLICATION); // 图标
    wndclass.hCursor  =  LoadCursor(NULL,IDC_ARROW); // 光标
    wndclass.hbrBackground  =  (HBRUSH)GetStockObject(WHITE_BRUSH); // 画刷
    wndclass.lpszMenuName   =  NULL; // 菜单
    wndclass.lpszClassName  =  szClassName; // 类名称

    
// 注册窗口类
     if ( ! RegisterClass ( & wndclass))
    {
           MessageBox (NULL, TEXT (
" RegisterClass Fail! " ), 
                   szClassName, MB_ICONERROR);
           
return   0 ;
    }

 

    
// 建立窗口
    HWND hwnd;
    hwnd 
=  CreateWindow(szClassName, // 窗口类名称
           TEXT ( " The Simple Win32 Application " ), // 窗口标题 
           WS_OVERLAPPEDWINDOW, // 窗口风格,即通常我们使用的windows窗口样式
           CW_USEDEFAULT, // 指定窗口的初始水平位置,即屏幕坐标系的窗口的左上角的X坐标
           CW_USEDEFAULT, // 指定窗口的初始垂直位置,即屏幕坐标系的窗口的左上角的Y坐标
           CW_USEDEFAULT, // 窗口的宽度
           CW_USEDEFAULT, // 窗口的高度
           NULL, // 父窗口句柄
           NULL, // 窗口菜单句柄
           hInstance, // 实例句柄
           NULL);

    ShowWindow(hwnd,iCmdShow);
// 显示窗口
    UpdateWindow(hwnd); // 立即显示窗口



    
// 消息循环
    MSG msg;

    
/*
    GetMessage()从消息队列中取消息,对取出的消息进行转换(TranslateMessage),
    对于能够将虚拟键码转化成字符码的消息,会在消息队列里放一条WM_CHAR消息,
    最后将消息发送到相应的消息处理函数进行处理。
    循环执行这个处理过程,直到收到WM_QUIT消息,才退出循环,结束程序。
    
*/
    
while (GetMessage( & msg, 0 , 0 , 0 )) // 从消息队列中取消息 
    {
           TranslateMessage (
& msg);               // 转换消息
           DispatchMessage ( & msg);                // 派发消息
    }
    
return  msg.wParam;
    
/* ---------------GetMessage---------------------------------
    GetMessage

    函数原型:
    BOOL GetMessage(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax);

    参数:
    lpMsg:一个指向MSG结构的指针,该结构用于存放从消息队列里取出的消息。
    hWnd:窗口句柄。如果该参数是非零值,则GetMessage只检索该窗口(也包括其子窗口)消息,如果为零,则GetMessage检索整个进程内的消息。
    wMsgFilterMin:指定被检索的最小消息值,也就是消息范围的下界限参数。
    wMsgFilterMax:上界限参数。如果wMsgFilterMin和wMsgFilterMax都为零,则不进行消息过滤,GetMessage检索所有有效的消息。

    返回值:
    GetMessage检索到WM_QUIT消息,返回值是零;其它情况,返回非零值。

    函数功能:
    这个API函数用来从消息队列中“摘取”一个消息,放到lpMsg所指的变量里。(注:如果所取窗口的消息队列中没有消息,则程序会暂停在GetMessage(…) 函数里,不会返回。)
    再通俗一点讲解GetMessage函数:
    当程序执行GetMessage()的时候,会检查消息队列,如果有消息在消息队列里,它取出该消息,将该消息填充到lpMsg所指的MSG结构,并返回TRUE值。如果此时消息队列里没有消息(消息队列为空),它会将线程阻塞,也就是将控制权交给系统,直到消息队列中有内容时,才唤醒线程继续执行。
    对于GetMessage()函数,还有一点需要说明,就是当从消息队列中取出的消息是WM_QUIT时,函数返回值是0。我们一般利用这一点退出消息循环,结束程序。
    ---------------------------------------------------------------
*/

    
/* ------------------TranslateMessage---------------------
    TranslateMessage 

    函数原型:

    BOOL TranslateMessage(CONST MSG*lpMsg);

    参数:
      IpMsg:指向MSG结构的指针,该结构是函数GetMessage或PeekMessage从消息队列里取得的消息。

     函数功能:
        该函数将虚拟键消息转换为字符消息。字符消息被寄送到调用线程的消息队列里,当下一次线程调用函数GetMessage或PeekMessage时被读出。
    什么是虚拟键码呢?Windows为了方便输入管理,减少程序对设备的依赖性,将键盘上所有的按键都用一个两位十六进制数对应,这些数称为虚拟键码。虚拟键码一般以VK_开头,如:Esc键对应的虚拟键码是VK_ESCAPE;空格键对应的虚拟键码是VK_SPACE;VK_LWIN与左边的Windows徽标键相对应。
    当一个按键被按下时,会触发WM_KEYDOWN消息, WM_KEYDOWN消息的wParam参数值就是虚拟键值。通过这个值就可以判断哪个键被按下了。
    为什么我们要把虚拟键码转换为字符码呢?
    比如我们按下了‘A’键,此时我们得到的字符可能是‘A’,也可能是小写的‘a’,这由当时的大写状态(Caps Lock)以及是否同时按下了Shift键有关。TranslateMessage()函数的作用就是不用我们考虑这些问题,而是根据这些情况,自动返回一个ASCII码值,以方便用户使用。
    并不是所有的虚拟键码值都会Translate成字符码。字母、数字键都有字符码相对应,而像方向箭头键、F1—F12功能键这些按键就没有字符码相对应。当虚拟键码需要转化成字符码时,TranslateMessage()函数就在消息队列里放一条WM_CHAR消息,WM_CHAR消息的wParam参数值就是转换后的ASCII码值。
    -------------------------------------------
*/

    
/* --------------------DispatchMessage-------------------
    DispatchMessage 

    函数原型:
    LONG DispatchMessage(CONST MSG *lpmsg);

    函数功能:
    它的作用很简单,就是分派消息到窗口的消息处理函数去执行。
    -------------------------------------------
*/

    
/* -----------------PeekMessage-------------
    PeekMessage

    函数原型:
    BOOL PeekMessage(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax,UINT wRemoveMsg);

    参数:
    lpMsg、hWnd、wMsgFilterMin、wMsgFilterMax这四个参数的意义和GetMessage对应参数的意义相同,在此不再赘述。
    wRemoveMsg:这个参数决定读消息时是否删除消息,可选值有PM_NOREMOVE和PM_REMOVE。如果您选PM_NOREMOVE,执行该函数后消息仍然留在消息队列(我称为读消息);如果您选PM_REMOVE,执行该函数后将在消息队列中移除该消息(同GetMessage())。

    返回值:
    消息队列中有消息,返回值为TRUE;消息队列中没有消息,返回值为FALSE。

    函数功能:
    PeekMessage()也是从消息队列中取消息,但它是GetMessage()不同,主要在以下两点:

    (一)、GetMessage()只能从消息队列中取走消息,也就是说,GetMessage()执行后,该消息将从消息队列中移除。
    PeekMessage()可以从消息队列中取走消息。也可以读消息,让消息继续留在消息队列里。

    (二)、当消息队列中没有消息时,GetMessage()将会阻塞线程,等待消息;而PeekMessage()与GetMessage()不同,它执行后会立刻返回,消息队列中有消息时,返回值为TRUE;消息队列中没有消息时,返回值为FALSE。

    ------------------------------------
*/

    
/* -------------------PeekMessage版的消息循环---------------------------
    //消息循环
    MSG msg;

    while(true)
    {
          if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) //从消息队列中取消息
          {
                  if(msg.message == WM_QUIT)
                        break;
                  TranslateMessage (&msg);           //转换消息
                  DispatchMessage (&msg);            //派发消息
           }
           else
                  WaitMessage();

    } //End of while(true)
    
*/

    
/* ------------------WaitMessage--------------------------
    WaitMessage

    函数原型:
    BOOL WaitMessage(VOID);

    函数功能:
    这个函数的作用是当消息队列中没有消息时,将控制权交给其它线程。该函数将会使线程挂起,直到消息队列中又有新消息。
    这个函数专门和PeekMessage配合使用,当消息队列中没有消息时,挂起线程,等待消息队列中新消息的到来,这样可以减轻CPU的运算负担。
    --------------------------------------------------
*/
}

// 消息处理函数

// 参数:窗口句柄,消息,消息参数,消息参数

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    
// 处理感兴趣的消息
     switch  (message)
    {
        
case  WM_DESTROY:
            
// 当用户关闭窗口,窗口销毁,程序需结束,发退出消息,以退出消息循环
            PostQuitMessage( 0 );
            
return   0 ;
    }
    
// 其他消息交给由系统提供的缺省处理函数
     return  ::DefWindowProc (hwnd, message, wParam, lParam);
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值