WindowsSDK入门系列(2) Timer的使用

WindowsSDK入门系列(2) Timer的使用

 

现在是4点,距离下班还有一个小时时间,准备再复习一下SDK

由于MFC使用了很长时间,总是有想返回去好好研究一下SDK的冲动。无奈时间有限,只能复习个一鳞半爪。

 

通过本文能够了解到:

Timer的使用

 

第一部分:工程做成

    VC 6.0下面新建--Win32 Application ,在项目名处填写testTimer,点击OK,在下一页选择中间的选项,点击完成。一个空空如也的项目建立完毕。

int APIENTRY WinMain(HINSTANCE hInstance,

                     HINSTANCE hPrevInstance,

                     LPSTR     lpCmdLine,

                     int       nCmdShow )

{

              return 0;

}

 

第二部分:添加骨肉

    可以将SDK骨架简单记忆成:InitAppInitInstance,Message循环,再加上一个WinProc四部分就可以了。雏形就不多说了。内容如下:

    testTimer.cpp

 

#include  " myresource.h "

 

BOOL InitApp(HINSTANCE hInst, LPCSTR szClassName);

BOOL InitInstance(HINSTANCE hInst, LPCSTR szClassName, 
int  nCmdShow);

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp);

 

int  APIENTRY WinMain(HINSTANCE hInstance,

                     HINSTANCE hPrevInstance,

                     LPSTR     lpCmdLine,

                     
int        nCmdShow )

{

             MSG msg;

    
char  szClassName[]  =   " timer " ;

    

    
if  ( ! hPrevInstance) 

              {

        
if  ( ! InitApp(hInstance, szClassName))

            
return  FALSE;

    }

    
if  ( ! InitInstance(hInstance, szClassName, nCmdShow)) 

              {

        
return  FALSE;

    }

    
while  (GetMessage( & msg, NULL,  0 0 )) 

              {

        TranslateMessage(
& msg);

        DispatchMessage(
& msg);

    }

   
return  msg.wParam;

}

 

//  Windows register == MFC's PreCreateWindow

BOOL InitApp(HINSTANCE hInst, LPCSTR szClassName)

{

    WNDCLASS wc;

    wc.style 
=  CS_HREDRAW  |  CS_VREDRAW;

    wc.lpfnWndProc 
=  WndProc;     //  Window Proc's Name 

    wc.cbClsExtra 
=   0 ;

    wc.cbWndExtra 
=   0 ;

    wc.hInstance 
=  hInst;         //  Instance

    wc.hIcon 
=  LoadIcon(NULL, IDI_APPLICATION);

    wc.hCursor 
=  LoadCursor(NULL, IDC_ARROW);

    wc.hbrBackground 
=  (HBRUSH)GetStockObject(WHITE_BRUSH);

    wc.lpszMenuName 
=   " TIMERMENU " ;     //  Menu

    wc.lpszClassName 
=  (LPCSTR)szClassName;

    
return  (RegisterClass( & wc));

}

 

//  Create Windows

BOOL InitInstance(HINSTANCE hInst, LPCSTR szClassName, 
int  nCmdShow)

{

    HWND hWnd;

    hWnd 
=  CreateWindow(szClassName,

            
" Timer " ,                                                   //  Disp in Title bar

            WS_OVERLAPPEDWINDOW,    
//  Window's kind

            CW_USEDEFAULT,                              
//

            CW_USEDEFAULT,                              
//

            CW_USEDEFAULT,                              
// Width

            CW_USEDEFAULT,                              
// Hight

            NULL,                                                                  
//  Parent's handle

            NULL,                                                                  
//  menu's handle

            hInst,                                                                   
//  instanse 's handle

            NULL);

    
if  ( ! hWnd)

        
return  FALSE;

    ShowWindow(hWnd, nCmdShow);

    UpdateWindow(hWnd);

    
return  TRUE;

}

 

// WndProc

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)

{

    
switch  (msg) {

        
case  WM_COMMAND:                    //  Click Menu

            
switch  (LOWORD(wp)) 

                                          {

                
case  IDM_END:     //  Menu's “Exit” Clicked

                    SendMessage(hWnd, WM_CLOSE, 
0 0L );

                    
break ;

                
default :

                    
break ;

            }

            
break ;

        
case  WM_DESTROY:

            PostQuitMessage(
0 );

            
break ;

        
default :                                             //  calls the default window procedure

            
return  (DefWindowProc(hWnd, msg, wp, lp));

    }

    
return   0L ;

}

 

 

追加的File

myresource.h

#define IDM_END 1000

 

testTimer.rc

 

#include  " myresource.h "

 

/////////////////////////////////////////////////////////////////////////// //

//

//  Menu

//

 

TIMERMENU MENU DISCARDABLE 

BEGIN

    MENUITEM 
" Exit " ,                        IDM_END

END

 

 

框架做好了。编译一下,是不是可以生成一个最基本的程序框架了?

此框架啥都没做,点击一下Exit。程序退出。

 

第三部分:Timer的使用

好多人估计还不熟悉SDK框架,以后有时间我会补一个框架介绍,并暂定今天的标题为WindowsSDK入门系列,同时说明我的复习的内容均Copy自网上,如有雷同,概不负责。

    我想使用的Timer很简单,就是在程序界面上面,每一秒更新一次时间。就跟Windows右下角的那个钟表一样。

    先看一下SetTimer的原型

UINT_PTR SetTimer(          HWND hWnd, // 接受Timer消息的窗口句柄

    UINT_PTR nIDEvent,                               // timerID

    UINT uElapse,                                       // 经过时间,毫秒为单位

    TIMERPROC lpTimerFunc // Timer的回调函数

);

这个设定一开始,Windows就会按时(根据uElapse)向程序发送WM_TIMER消息了。如果将回调函数设置为NULL,那么该消息能就在WndProc中获得。

要想停止Timer,只需要调用函数

BOOL KillTimer(          HWND hWnd,

    UINT_PTR uIDEvent

);

传入Window 句柄,跟TimerID即可关闭timer

 

主要函数说完了,先看代码,然后再说说需要注意的细节。

 

#include  " stdafx.h "

#include 
< time.h >

#include 
< stdio.h >

#include 
" myresource.h "

 

BOOL InitApp(HINSTANCE hInst, LPCSTR szClassName);

BOOL InitInstance(HINSTANCE hInst, LPCSTR szClassName, 
int  nCmdShow);

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp);

int  GetTimeStr( void );

 

char  time_str[ 256 ];

 

 

int  APIENTRY WinMain(HINSTANCE hInstance,

                     HINSTANCE hPrevInstance,

                     LPSTR     lpCmdLine,

                     
int        nCmdShow )

{            MSG msg;

    
char  szClassName[]  =   " timer " ;

    

    
if  ( ! hPrevInstance) 

              {

        
if  ( ! InitApp(hInstance, szClassName))

            
return  FALSE;

   }

    
if  ( ! InitInstance(hInstance, szClassName, nCmdShow)) 

              {

        
return  FALSE;

    }

    
while  (GetMessage( & msg, NULL,  0 0 )) 

              {

        TranslateMessage(
& msg);

        DispatchMessage(
& msg);

    }

    
return  msg.wParam;

}

 

//  Windows register == MFC's PreCreateWindow

BOOL InitApp(HINSTANCE hInst, LPCSTR szClassName)

{

    WNDCLASS wc;

    wc.style 
=  CS_HREDRAW  |  CS_VREDRAW;

    wc.lpfnWndProc 
=  WndProc;     //  Window Proc's Name 

    wc.cbClsExtra 
=   0 ;

    wc.cbWndExtra 
=   0 ;

    wc.hInstance 
=  hInst;         //  Instance

    wc.hIcon 
=  LoadIcon(NULL, IDI_APPLICATION);

    wc.hCursor 
=  LoadCursor(NULL, IDC_ARROW);

    wc.hbrBackground 
=  (HBRUSH)GetStockObject(WHITE_BRUSH);

    wc.lpszMenuName 
=   " TIMERMENU " ;     //  Menu

    wc.lpszClassName 
=  (LPCSTR)szClassName;

    
return  (RegisterClass( & wc));

}

 

//  Create Windows

BOOL InitInstance(HINSTANCE hInst, LPCSTR szClassName, 
int  nCmdShow)

{

    HWND hWnd;

    hWnd 
=  CreateWindow(szClassName,

            
" Timer " ,                                                   //  Disp in Title bar

            WS_OVERLAPPEDWINDOW,    
//  Window's kind

            CW_USEDEFAULT,                              
//

            CW_USEDEFAULT,                              
//

            
320 ,                                                                       // Width

            
100 ,                                                                                     // Hight

            NULL,                                                                  
//  Parent's handle

            NULL,                                                                  
//  menu's handle

            hInst,                                                                   
//  instanse 's handle

            NULL);

    
if  ( ! hWnd)

        
return  FALSE;

    ShowWindow(hWnd, nCmdShow);

    UpdateWindow(hWnd);

    
return  TRUE;

}

 

// WndProc

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)

{

              PAINTSTRUCT ps;

    HDC hdc;

    
int  id;

 

    
switch  (msg)              {

                            
case  WM_CREATE:

            
if (SetTimer(hWnd, ID_MYTIMER,  1000 , NULL)  ==   0

                                          {

                    MessageBox(hWnd,(LPCSTR)
" Fail " ,(LPCSTR) " Fail " , MB_OK  |  MB_ICONEXCLAMATION);

            }

            
break ;

        
case  WM_TIMER:

            GetTimeStr();

            InvalidateRect(hWnd, NULL, TRUE);

            
break ;

        
case  WM_PAINT:

           hdc 
=  BeginPaint(hWnd,  & ps);

            TextOut(hdc, 
50 15 , (LPCSTR)time_str, strlen(time_str));

            EndPaint(hWnd, 
& ps);

            
break ;

        
case  WM_COMMAND:                    //  Click Menu

            
switch  (LOWORD(wp)) 

                                          {

                
case  IDM_END:     //  Menu's 乬Exit乭 Clicked

                    SendMessage(hWnd, WM_CLOSE, 
0 0L );

                    
break ;

                
default :

                    
break ;

            }

            
break ;

                            
case  WM_CLOSE:

            id 
=  MessageBox(hWnd,

                (LPCSTR)
" Really Quit? " ,

                (LPCSTR)
" Quit " ,

                MB_YESNO 
|  MB_ICONQUESTION);

            
if  (id  ==  IDYES) {

                                                        

                
if (KillTimer(hWnd, ID_MYTIMER)  ==  TRUE) {

                                                                      
/*

                    MessageBox(hWnd,

                        (LPCSTR)"timer was killed",

                        (LPCSTR)"kill timer success",

                        MB_OK | MB_ICONEXCLAMATION);
*/

                }

                DestroyWindow(hWnd);

            }

            
break ;

        
case  WM_DESTROY:

            PostQuitMessage(
0 );

            
break ;

        
default :                                             //  calls the default window procedure

            
return  (DefWindowProc(hWnd, msg, wp, lp));

    }

    
return   0L ;

}

 

int  GetTimeStr( void )

{

    
char   * str_org  =   " %2d年%d月%2d日 %2d时%2d分%2d秒 " ;

  

              SYSTEMTIME stSystemTime;

              ::GetLocalTime(
& stSystemTime);

              sprintf(time_str, str_org,

        stSystemTime.wYear,stSystemTime.wMonth , stSystemTime.wDay, 

        stSystemTime.wHour,stSystemTime.wMinute, stSystemTime.wSecond

        );

 

    
return   0 ;

}

 

 

咳咳,现在说一下“要点”,其实也算不上什么要点。就是一些细节而已。把细节掌握多了,对程序也就会更加了解。

 

1.      我们将SetTimer放在WM_CREATE消息中执行,这个消息是在CreateWindow执行,创建了hWnd句柄后,我们才能将hWnd传入SetTimer的以一个参数不是。

 

2.      KillTimer可以放到WM_DESTROY中执行,如果你想要在停止前还做到什么其他动作。比如我想在停止前弹一个消息框,就可以在WM_CLOSE中添加,注意因为你可以调用Hook这个消息,但是一定要将他要做的事情也顺带做好了。WM_CLOSE自己要做什么?DestroyWindow(hWnd)DestroyWindow将会发送WM_DESTROY消息。

 

 

3.      Menu消息是通过WM_COMMAND来获得的。

 

4.      WM_PAINT在这个消息中一般用BeginPaintEndPaint搭对使用,来获得和销毁句柄。

如果在其他地方,使用GetDC(),ReleaseDC MFC中,直接用那个dc(this)就可以了。

 

5.      GetTimeStr使用GetLocalTime来获取系统当前时间。

 

6.      关于屏幕刷新InvalidateRect  BOOL InvalidateRect(

HWND hWnd,

 const RECT* lpRect,

 BOOL bErase

hWnd为要刷新句柄,lpRect为刷新区域,指定NULL为刷新整个区域。bEraseFASLE是不刷新背景。

 

End

你可能感兴趣的:(WindowsSDK入门系列(2) Timer的使用)