现在的位置: 首页 > 综合 > 正文

初学Windows编程笔记1——窗口和消息

2013年04月29日 ⁄ 综合 ⁄ 共 3554字 ⁄ 字号 评论关闭

 

Windows程序设计(第五版)

第三章 窗口与消息

源程序见原书39页

在Visual Studio 2010 C++下测试


//------------------Start-------------------

#include <windows.h>
        
void ShowMessage(LPCWSTR text)
{
    MessageBox(NULL, text, TEXT("ShowMessage"), 0) ;
}

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM) ;        

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
    static TCHAR szAppName[] = TEXT ("Hello World!") ;

    HWND   hwnd ;
    MSG    msg ;

    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 (GRAY_BRUSH) ;
    wndclass.lpszMenuName  = NULL ;
    wndclass.lpszClassName= szAppName ;


   
RegisterClass(&wndclass);//Register


    hwnd = CreateWindow( szAppName,      // window class name       

                   TEXT ("Hello World Program"),   // window caption
                   WS_OVERLAPPEDWINDOW,  // window style
                   CW_USEDEFAULT,// initial x position
                   CW_USEDEFAULT,// initial y position
                   CW_USEDEFAULT,// initial x size
                   CW_USEDEFAULT,// initial y size
                   NULL,         // parent window handle
                   NULL,            // window menu handle
                   hInstance,   // program instance handle
                   NULL) ;      // creation parameters
    /*
    CreateWindow的过程中便会开始调用CALLBACK WndPROC
    */

    ShowWindow
(hwnd, iCmdShow);
       
    UpdateWindow (hwnd); //好像有没有这个updateWin效果都一样   

    
        
    while (GetMessage (&msg, NULL, 0, 0))
    {
    //if(msg.message == (UINT)WM_RBUTTONDOWN)//debug
    //    {MessageBox (  NULL, TEXT ("Right B D"), TEXT("Halo"), 0);}

        TranslateMessage
(&msg);//注释掉对好像当前程序没有影响[翻译一些键盘消息?]
        
        
DispatchMessage
(&msg) ;

        /*DispatchMessage(...)
        [我认为应该是将消息(控制权)返回给Window(附带着将消息发送给窗口过程)]

  注释掉之后,右上角的最小最大关闭三个按钮失效.

        且注释掉之后对窗口的操作都不会回调给WndProc(...)处理
        */

        

    //if(msg.message == (UINT)WM_RBUTTONDOWN)
       // {MessageBox (  NULL, TEXT ("Right B D3"), TEXT("Halo"), 0);}

    }
        
    return msg.wParam ;        
}
        
//这个WndProc的调用真是非常诡异
//一般情况下,确实是跟在DispatchMessage之中的
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HDC hdc;       
    PAINTSTRUCT ps;

    RECT rect;
        
    switch (message)
    {
        
    case WM_RBUTTONDOWN:
        MessageBox (  NULL, TEXT ("Right B D CALLBACK"), TEXT("Halo"), 0) ;
        return 0;

    case WM_CREATE:        
        MessageBox (  NULL, TEXT ("Window is Creating."), TEXT("Halo"), 0) ;
        return 0 ;

    case   WM_PAINT:
        /*
        在ShowWindow的过程中就会开始Paint,而且这个过程会重复40次左右。为什么会重复这么多次?
        */
            //ShowMessage(TEXT("WM_Paint"));//debug

            hdc = BeginPaint (hwnd, &ps) ;

            GetClientRect (hwnd, &rect) ;
        
            DrawText (hdc, TEXT ("Hello, Windows 98!"), -1, &rect,
        
            DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;
        
            EndPaint (hwnd, &ps) ;
        
            return 0 ;
        
    case   WM_DESTROY:
            //如果是销毁窗口消息

            MessageBox(NULL, TEXT ("Win Destroying..."), TEXT("Halo"), 0) ;

            PostQuitMessage
(0) ;
        
            return 0;

    default:
        return DefWindowProc
(hwnd, message, wParam, lParam) ;
    }
}

//------END------

 


(1)新建一个窗口。 此过程分3步走

(1.1)声明(并赋初值)WndCLASS wndclass;

(1.2)注册窗口类 RegisterClass(...);//只有注册过的窗口类才会产生回调

(1.3)创建窗口CreateWindow(...);//这期间将会第一次回调WndProc(...)


(2)显示窗口 ShowWindow(...);期间会(多次)回调WndProc(...) ,并发送WM_PAINT消息


(3)UpdateWindow(...);//更新窗口


(4)不断地循环接受各种消息(在窗口成型后)

While(GetMessage(..))

{

TranslateMessage(...);//翻译消息

DispatchMessage(...);//窗口成型之后,所有的回调都来自于他,如果注释掉,在窗口成型之后将不会回调WndProc()

}

抱歉!评论已关闭.