zoukankan      html  css  js  c++  java
  • 走进windows编程的世界-----消息处理函数(2)

    一 WM_PAINT消息

     1 WM_PAINT的产生
       因为窗体的互相覆盖等,产生须要绘制的区域,那么会产生WM_PAINT消息.
       普通情况下,不直接发送WM_PAINT消息,通过API声明须要绘制区域,来产生WM_PAINT消息.
       比如,能够使用InvalidateRect声明一个须要又一次绘制的区域.
      
      2 WM_PAINT的注意点
        2.1 假设一个消息队列中,有多个WM_PAINT消息,仅仅有最后一个WM_PAINT消息会被处理.
        2.2 WM_PAINT消息处理中,要清空须要被绘制的区域. BeginPaint
          
      3 WM_PAINT的使用
        3.1 WM_PAINT開始时,必须调用BeginPaint
        3.2 绘制图形
        3.3 WM_PAINT处理后,必须调用EndPaint

     看以下的演示样例代码:

    /* File : winpaint.cpp
     * Auth : sjin
     * Date : 20140706
     * Mail : 413977243@qq.com
     */
    
    #include <Windows.h>
    #include <stdio.h>
    
    
    HINSTANCE g_hInst = NULL;
    
    void OnPaint(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
    {
        PAINTSTRUCT ps = {0};
    	/*WM_PAINT開始时。必须调用的*/
        HDC hDC = BeginPaint(hWnd, &ps);
    
        CHAR szText[] = "Hello WM_PAINT";
    	/*在指定的坐标下输出一行字*/
        TextOut(hDC, 100, 100, szText, strlen(szText));
    
    	/*绘制一个矩形*/
        Rectangle(hDC, 200, 200, 300, 300);
    
    	EndPaint(hWnd,&ps);
    }
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
    {
        switch(nMsg)
        {
        case WM_PAINT:
            OnPaint(hWnd, nMsg, wParam, lParam); 
    		break;
        case WM_DESTROY:
            PostQuitMessage(0); 
    		return 0;
        }
        return DefWindowProc(hWnd, nMsg, wParam, lParam);
    }
    
    BOOL RegisterWnd(LPSTR lpszClassName)
    {
        WNDCLASSEX wce = {0};
        wce.cbClsExtra = 0;
        wce.cbSize = sizeof(wce);
        wce.cbWndExtra = 0;
        wce.hbrBackground = HBRUSH(COLOR_BTNFACE + 1);
        wce.hCursor = NULL;
        wce.hIcon = NULL;
        wce.hIconSm = NULL;
        wce.hInstance = g_hInst;
        wce.lpfnWndProc = WndProc;
        wce.lpszClassName = lpszClassName;
        wce.lpszMenuName = NULL;
        wce.style = CS_HREDRAW|CS_VREDRAW;
    
        ATOM nAtom = RegisterClassEx(&wce);
        if(0 == nAtom)
        {
            return FALSE;
        }
        return TRUE;
    }
    
    HWND CreateWnd(LPSTR lpszClassName)
    {
        HWND hWnd = CreateWindowEx(0,
            lpszClassName, "MyWndPaint", WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
            NULL, NULL, g_hInst, NULL);
        return hWnd;
    }
    
    void DisplayWnd(HWND hWnd)
    {
        ShowWindow(hWnd, SW_SHOW);
        UpdateWindow(hWnd);
    }
    
    void Message()
    {
        MSG msg = {0};
        while(GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    
    int APIENTRY WinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPSTR     lpCmdLine,
                         int       nCmdShow)
    {
         g_hInst = hInstance;
        RegisterWnd("MyWndPaint");
        HWND hWnd = CreateWnd("MyWndPaint");
        DisplayWnd(hWnd);
        Message();
        return 0;
    }

    三 键盘消息

      1 键盘消息
       按键消息
         WM_KEYDOWN 当键被按下时产生
         WM_KEYUP 当键被释放时产生
         WM_SYSKEYDOWN 当系统键被按下时产生 ALT/F10
         WM_SYSKEYUP 当系统键释放时产生
        字符消息
         WM_CHAR 当有字符键被按下时产生
          TranslateMessage会将WM_KEYDOWN消息中,能够显示的按键,转换成WM_CHAR的消息
      2 消息參数
        WPARAM - 虚拟键码
        LPARAM - 相关的按键信息.
      
      3 消息的使用
        3.1 当有按键消息时,首先进入系统消息队列,然后被程序的消息循环获取.
        3.2 消息的处理
      4 键盘消息的顺序
        对于可显示字符: WM_KEYDOWN,WM_CHAR,WM_KEYUP
        对于不可显示字符: WM_KEYDOWN,WM_KEYUP
        对于系统键:WM_SYSKEYDOWN,WM_SYSKEYUP
        假设按键一直不释放,会反复产生
             WM_KEYDOWN(WM_CHAR)


    /* File : winKeyboard.cpp
     * Auth : sjin
     * Date : 2014-07-06
     * Mail : 413977243@qq.com
     */
    
    #include <Windows.h>
    #include <stdio.h>
    
    
    HINSTANCE g_hInst = NULL;
    HANDLE g_hStdOut = NULL;
    
    LRESULT CALLBACK WinProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
    {
        switch(nMsg)
        {
        case WM_KEYDOWN:/*键盘按下*/
            {
                CHAR szText[] = "WM_KEYDOWN
    ";
                switch(wParam)
                {
                case VK_LEFT:
                case VK_RIGHT:
                case VK_UP:
                case VK_DOWN:
                    WriteConsole(g_hStdOut, szText, strlen(szText), NULL, NULL);
                    break;
                }
            }
            break;
        case WM_KEYUP:/*键盘抬起*/
            {
                CHAR szText[] = "WM_KEYUP
    ";
                WriteConsole(g_hStdOut, szText, strlen(szText), NULL, NULL); break;
            }
            break;
        case WM_SYSKEYDOWN:/*系统键按下*/
            {
                CHAR szText[] = "WM_SYSKEYDOWN
    ";
                WriteConsole(g_hStdOut, szText, strlen(szText), NULL, NULL); break;
            }
            break;
        case WM_SYSKEYUP:/*系统键抬起*/
            {
                CHAR szText[] = "WM_SYSKEYUP
    ";
                WriteConsole(g_hStdOut, szText, strlen(szText), NULL, NULL); break;
            }
            break; 
        case WM_CHAR:/*字符键盘*/
            {
                CHAR szText[260] = {0};
                sprintf(szText, "WM_CHAR: %c
    ", wParam);
                WriteConsole(g_hStdOut, szText, strlen(szText), NULL, NULL); break;
            }
            break;
        case WM_DESTROY:
            PostQuitMessage(0); return 0;
        }
        return DefWindowProc(hWnd, nMsg, wParam, lParam);
    }
    
    BOOL ResiterWnd(LPSTR lpszClassName)
    {
        WNDCLASSEX wce = {0};
        wce.cbClsExtra = 0;
        wce.cbSize = sizeof(wce);
        wce.cbWndExtra = 0;
        wce.hbrBackground = HBRUSH(COLOR_BTNFACE+1);
        wce.hCursor = NULL;
        wce.hIcon = NULL;
        wce.hIconSm = NULL;
        wce.hInstance = g_hInst;
        wce.lpfnWndProc = WinProc;
        wce.lpszClassName = lpszClassName;
        wce.lpszMenuName = NULL;
        wce.style = CS_HREDRAW|CS_VREDRAW;
    
        ATOM nAtom = RegisterClassEx(&wce);
        if(0==nAtom)
        {
            return FALSE;
        }
        return TRUE;
    }
    
    HWND CreateWnd(LPSTR lpszClassName)
    {
        HWND hWnd = CreateWindowEx(0, lpszClassName, "MyWnd",
            WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT,
            NULL, NULL, g_hInst, NULL);
        return hWnd;
    }
    
    void ShowWnd(HWND hWnd)
    {
        ShowWindow(hWnd, SW_SHOW);
        UpdateWindow(hWnd);
    }
    
    void Message()
    {
        MSG msg = {0};
        while(GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    
    void NewConsole()
    {
    	/*产生控制台*/
        AllocConsole();
    
    	/*获得控制台标准输出流句柄*/
        g_hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
        CHAR szText[] = "Debug Message......:
    ";
    	/*将szText 写到控制台*/
        WriteConsole(g_hStdOut, szText, strlen(szText), NULL, NULL);
    }
    
    int APIENTRY WinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPSTR     lpCmdLine,
                         int       nCmdShow)
    {
    	/*产生命令行窗体。用来调试程序*/
        NewConsole();
         g_hInst = hInstance;
        ResiterWnd("MyWnd");
        HWND hWnd = CreateWnd("MyWnd");
        ShowWnd(hWnd);
        Message();
    
        return 0;
    }

    三  鼠标消息

      1 鼠标消息
        1) 基本鼠标消息
        WM_LBUTTONDOWN   左键按下
        WM_LBUTTONUP     左键抬起
        WM_RBUTTONDOWN   右键按下
        WM_RBUTTONUP     右键抬起
        WM_MOUSEMOVE     鼠标移动
        2) 双击消息
        WM_LBUTTONDBLCLK 左键双击 
        WM_RBUTTONDBLCLK 右键双击
        3) 滚轮消息
        WM_MOUSEWHEEL    鼠标滚轮

      2 消息的參数
        WPARAM - 当前键盘和鼠标按键状态,比如MK_CONTROL/MK_SHIFT,MK_LBUTTON等
        LPARAM - 当前鼠标的坐标,坐标的原点是窗体客户区的左上角.
           X坐标 - LOWORD(lParam),低16位
           Y坐标 - HIWORD(lParam),高16位
        參数详细内容和详细鼠标消息有略微不同. 
        
      3 消息的使用
      
        3.1 基本鼠标消息,仅仅需在窗体处理函数添加消息处理就可以. 当消息来临,获取鼠标和按键状态.比如:

    case WM_MOUSEMOVE:
    {
        int nX = LOWORD(lParam);
        int nY = HIWORD(lParam);
    }

        附:坐标转换的函数 ClientToScreen能够将鼠标坐标转换为屏幕的坐标.

       3.2 双击消息
       3.2.1 窗体注冊要添加 CS_DBLCLKS 类型
        wce.style = CS_DBLCLKS|...;
       3.2.2 在窗体处理函数中添加消息处理
       3.2.3 产生过程,比如:WM_LBUTTONDBLCLK
          WM_LBUTTONDOWN
          WM_LBUTTONUP
          WM_LBUTTONDBLCLK
          WM_LBUTTONUP
          连续两次LBUTTONDOWN的时间间隔小于预定的双击时间间隔,就会产生LBUTTONDBLCLK消息. 
          双击时间间隔能够通过控制面板调整.

     3.3 滚轮消息
      3.3.1 因为WM_MOUSEWHEEL须要Winnt4.0以上版本号支持,所以须要包括在windows.h的头文件前,添加 _WIN32_WINNT 宏定义,
            #define _WIN32_WINNT 0x0400
        3.3.2 在窗体处理函数中添加消息处理
        3.3.3 參数
         LPARAM 与其他鼠标消息类同
         WPARAM - LOWORD(WPARAM) 表示按键状态
                  HIWORD(WPARAM) 滚轮滚动幅度,
                    120的倍数,能够为正负值.
            正值: 滚轮向上滚动, 一般窗体向上滚动
            负值: 滚轮向下滚动, 一般窗体向下滚动

    /* File : winCursor.cpp
     * Auth : sjin
     * Date : 2014-07-06
     * Mail : 413977243@qq.com
     */
    
    #include <Windows.h>
    #include <stdio.h>
    
    int g_nXPos = 0;
    int g_nYPos = 0;
    int g_nX1Rect = 0;
    int g_nY1Rect = 0;
    int g_nX2Rect = 0;
    int g_nY2Rect = 0;
    
    HINSTANCE g_hInst   = NULL;
    HANDLE    g_hStdOut = NULL;
    
    void PrintLog(LPSTR lpszLog)
    {
        WriteConsole(g_hStdOut, lpszLog, strlen(lpszLog), NULL, NULL);
    }
    
    void OnPaint(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
    {
        PAINTSTRUCT ps = {0};
        HDC hDC = BeginPaint(hWnd, &ps);
        CHAR szText[] = "Hello Mouse 12123";
        TextOut(hDC, g_nXPos, g_nYPos, szText, strlen(szText));
    
        Rectangle(hDC, g_nX1Rect, g_nY1Rect, g_nX2Rect, g_nY2Rect);
        EndPaint(hWnd, &ps);
    }
    
    LRESULT CALLBACK WndProc( HWND hWnd,
                              UINT nMsg,
                              WPARAM wParam,
                              LPARAM lParam )
    {
        switch( nMsg )
        {
        case WM_PAINT:
            OnPaint(hWnd, nMsg, wParam, lParam); break;
        case WM_LBUTTONDOWN:/*鼠标左键按下*/
            {
                PrintLog("WM_LBUTTONDOWN
    ");
                g_nX1Rect = LOWORD(lParam);
                g_nY1Rect = HIWORD(lParam);
            }
            break;
        case WM_LBUTTONUP:/*鼠标左键抬起*/
            {
                PrintLog("WM_LBUTTONUP
    ");
                g_nX2Rect = LOWORD(lParam);
                g_nY2Rect = HIWORD(lParam);
    			/*窗体更新区域加入一个矩形。背景将会擦出
    			 * 会触发WM_PAINT消息。
    			 */
                InvalidateRect(hWnd, NULL, TRUE);
            }
            break;
        case WM_RBUTTONDOWN:/*鼠标右键按下*/
            PrintLog("WM_RBUTTONDOWN
    ");
            break;
        case WM_RBUTTONUP:/*鼠标右键抬起*/
            PrintLog("WM_RBUTTONUP
    ");
            break;
        case WM_MOUSEMOVE:/*鼠标移动*/
            {
                int nX = LOWORD(lParam);
                int nY = HIWORD(lParam);
                POINT ptScreen = {0};
                ptScreen.x = nX;
                ptScreen.y = nY;
    			/*函数将指定点,或者矩形的用户坐标转换成屏幕坐标*/
                ClientToScreen(hWnd, &ptScreen);
    
                CHAR szText[260] = { 0 };
                sprintf( szText, 
                    "WM_MOUSEMOVE: X=%d(%d),Y=%d(%d)
    ",
                    nX, ptScreen.x, nY, ptScreen.y );
                PrintLog( szText );
                if( wParam & MK_CONTROL )
                {
                    PrintLog( "WM_MOUSEMOVE: MK_CONTROL
    " );
                }
                if( wParam & MK_LBUTTON )
                {
                    PrintLog( "WM_MOUSEMOVE: MK_LBUTTON
    " );
                }
    
                g_nXPos = LOWORD(lParam);
                g_nYPos = HIWORD(lParam);
                //InvalidateRect( hWnd, NULL, TRUE );
            }
            break;
        case WM_LBUTTONDBLCLK:/*左键双击*/
            PrintLog( "WM_LBUTTONDBLCLK
    " );
            break;
        case WM_RBUTTONDBLCLK:/*右键双击*/
            PrintLog( "WM_RBUTTONDBLCLK
    " );
            break;
        case WM_MOUSEWHEEL:/*鼠标滚轮移动*/
            {
                short nDelta = HIWORD(wParam);
                int nX = LOWORD(lParam);
                int nY = HIWORD(lParam);
                CHAR szText[260] = { 0 };
                sprintf( szText, 
                    "WM_MOUSEWHEEL: Detla=%d, X=%d,Y=%d
    ",
                    nDelta, nX, nY );
                PrintLog( szText );
            }
            break;
        case WM_DESTROY:
            PostQuitMessage( 0 );
            break;
        }
        return DefWindowProc( hWnd, nMsg,
            wParam, lParam );
    }
    
    BOOL RegisterWnd( LPSTR pszClassName )
    {
        WNDCLASSEX wce = { 0 };
        wce.cbSize          = sizeof( wce );
        wce.cbClsExtra      = 0;
        wce.cbWndExtra    = 0;
        wce.hbrBackground = HBRUSH(COLOR_WINDOW);
        wce.hCursor          = NULL;
        wce.hIcon          = NULL;
        wce.hIconSm       = NULL;
        wce.hInstance      = g_hInst;
        wce.lpfnWndProc   = WndProc;
        wce.lpszClassName = pszClassName;
        wce.lpszMenuName  = NULL;
        wce.style         = CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS;
        ATOM nAtom = RegisterClassEx( &wce );
        if( 0 == nAtom )
        {
            return FALSE;
        }
        return TRUE;
    }
    
    HWND CreateWnd( LPSTR pszClassName )
    {
        HWND hWnd = CreateWindowEx( 0,
            pszClassName, "MyWnd", 
            WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
            CW_USEDEFAULT, CW_USEDEFAULT, 
            CW_USEDEFAULT, NULL, NULL, 
            g_hInst, NULL );
        return hWnd;
    }
    
    void DisplayWnd( HWND hWnd )
    {
        ShowWindow( hWnd, SW_SHOW );
        UpdateWindow( hWnd );
    }
    
    void Message( )
    {
        MSG msg = { 0 };
        while( GetMessage( &msg, NULL, 0, 0 ) )
        {
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        }
    }
    
    void NewConsole()
    {
    	/*产生控制台*/
        AllocConsole();
    
    	/*获得控制台标准输出流句柄*/
        g_hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
        CHAR szText[] = "[sjin] Debug Message......:
    ";
    	/*将szText 写到控制台*/
        WriteConsole(g_hStdOut, szText, strlen(szText), NULL, NULL);
    }
    
    int APIENTRY WinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPSTR     lpCmdLine,
                         int       nCmdShow)
    {
         NewConsole( );
         g_hInst = hInstance;
        RegisterWnd( "MyWnd" );
        HWND hWnd = CreateWnd( "MyWnd" );
        DisplayWnd( hWnd );
        Message( );
    
        return 0;
    }


  • 相关阅读:
    ubuntu基本命令篇13用户管理
    网易邮箱繁体字信件乱码解决
    ubuntu基本命令篇16网络管理
    Ubuntu 10.04的安装
    DotNetNuke模块开发(一)
    查询进程打开的文件(转)
    Shell 的变量(转)
    Boot loader: Grub进阶(转)
    bash的通配符与特殊符号
    shell下的作业管理(转)
  • 原文地址:https://www.cnblogs.com/jhcelue/p/6951131.html
Copyright © 2011-2022 走看看