标题:windows sdk编程 -处理鼠标输入消息
只看楼主
tsjoy
Rank: 1
等 级:禁止访问
帖 子:13
专家分:0
注 册:2008-8-5
 问题点数:0 回复次数:2 
windows sdk编程 -处理鼠标输入消息
相关网站:http://edu.

WINDOWS将捕捉鼠标动作并把它们发送到相关窗口。这些活动包括左、右键按下、移动、双击新式鼠标还包括滚轮消息WM_WHEEL等。WINDOWS并不像处理键盘输入那样把所有的鼠标消息都导向有输入焦点的窗口,任何鼠标经过的窗口都将接收到鼠标消息,无论有否输入焦点。另外,窗口还会接收到鼠标在非客户区移动的消息(WM_NCMOVE),但大多数的情况下我们都会将其忽略掉。 对鼠标的每一个按钮都有两个消息:WM_LBUTTONDOWN,WM_RBUTTONDOWN 。对于三键鼠标还会有WM_MBUTTONDOWN和WM_MBUTTONUP消息,当鼠标在某窗口客户区移动时,该窗口将接收到WM_MOUSEMOVE消息。一个窗口若想处理WM_LBUTTONDBCLK或 WM_RBUTTONDBCLK,那么它的窗口类必须有CS_DBLCLKS风格,否则它就会接受到一堆的按键起落(WM_XBUTTONDOWN或WM_XBUTTONUP)的消息。 对于所有的消息,窗口过程函数传入的参数lParam包含了鼠标的位置,其中底位为x坐标,高位为y坐标,这些坐标值都是相对于窗口客户区的左上角的值,wParam中则包含了鼠标按钮的状态。
#include "Windows.h"
#include "tchar.h"

HWND hWinMain;
TCHAR szClassName[] = _T("MyClass");
TCHAR szCaptionMain[] = _T("My First Window!");
TCHAR FontName[] = _T("宋体");
WNDCLASSEX stdWndClass;
WPARAM keyChar = 0x20; //0x20是空格的ascii码,保证没有按键的时候程序正常显示。
BOOL MouseClick = FALSE;

POINT hitPoint;
LRESULT CALLBACK ProcWinMain(   HWND hWnd,
                       UINT Msg,
                       WPARAM wParam,
                       LPARAM lParam
)
{
    PAINTSTRUCT stPs;
    HDC hDC;
    HFONT hFont,hOldFont;
    switch(Msg)
    {
        case WM_PAINT:
        {
            hDC = BeginPaint(hWnd,&stPs);
            hFont = CreateFont(24,16,0,0,400,0,0,0,OEM_CHARSET,OUT_DEFAULT_PRECIS,
                CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH,FontName);

            hOldFont = (HFONT)SelectObject(hDC,hFont);
            SetTextColor(hDC,RGB(200,200,50));
            SetBkColor(hDC,RGB(0,0,255));
            TextOut(hDC,0,0,(char *)&keyChar,1);
            if(MouseClick)
            {
                TextOut(hDC,hitPoint.x,hitPoint.y,szCaptionMain,lstrlen(szCaptionMain));
            }
            SelectObject(hDC,hOldFont);
            EndPaint(hWnd,&stPs);
        }
        break;

        case WM_LBUTTONDOWN:
        {
             hitPoint.x = LOWORD(lParam);
            hitPoint.y = HIWORD(lParam);
            MouseClick = TRUE;
            InvalidateRect(hWnd,NULL,TRUE);
        }
        break;

        case WM_CHAR:
            {
                keyChar = wParam;
                InvalidateRect(hWnd,NULL,TRUE);
            }
            break;
        case WM_DESTROY:
        {
            PostQuitMessage(NULL);
        }
        break;

        default:
            return DefWindowProc(hWnd, Msg, wParam, lParam );
    }
    return 0;
}

int WINAPI WinMain(     HINSTANCE hInstance,
                        HINSTANCE hPrevInstance,
                        LPSTR lpCmdLine,
                        int nCmdShow
)
{
    MSG stMsg;
    WNDCLASSEX stdWndClass;
    RtlZeroMemory(&stdWndClass, sizeof(stdWndClass));
    stdWndClass.hCursor = LoadCursor(0,IDC_ARROW);
    stdWndClass.cbSize = sizeof(stdWndClass);
    stdWndClass.style = CS_HREDRAW|CS_VREDRAW;
    stdWndClass.lpfnWndProc = ProcWinMain;
    stdWndClass.hbrBackground = (HBRUSH)COLOR_WINDOW;
    stdWndClass.lpszClassName = szClassName;
    stdWndClass.hInstance = hInstance;

    RegisterClassEx(&stdWndClass);

    hWinMain = CreateWindowEx(WS_EX_CLIENTEDGE,szClassName,szCaptionMain,\
        WS_OVERLAPPEDWINDOW,100,100,600,400,NULL,NULL,hInstance,NULL);

    if(!hWinMain)
        return 0;
   
    ShowWindow(hWinMain,SW_SHOWNORMAL);
    UpdateWindow(hWinMain);


    while(GetMessage(&stMsg,NULL,0,0))
    {
        TranslateMessage(&stMsg);
        DispatchMessage(&stMsg);
    }

    return stMsg.wParam;
}


分析:
       case WM_LBUTTONDOWN:
        {
             hitPoint.x = LOWORD(lParam);
            hitPoint.y = HIWORD(lParam);
            MouseClick = TRUE;
            InvalidateRect(hWnd,NULL,TRUE);
        }
        break;
窗口过程处理了WM_LBUTTONDOWN消息,当接收到该消息时,lParam中包含了相对于窗口客户区左上角的坐标,我们把它保存下来,放到一个结构体变量(POINT)中,该结构体变量的定义如下:

typedef struct tagPOINT
{
       LONG x;
       LONG y;
} POINT, *PPOINT;

然后我们把标志量MouseClick设为TRUE,这表明至少有一次在客户区的左键按下消息。

            MouseClick = TRUE;

由于lParam是一个32位长的数,其中高、底16位分别包括了x、y坐标所以我们做一些小处理,以便保存它们。这里我们用到了两个宏LOWORD和HIWORD分别取出高16位和低16位的值。
这两个宏的定义位于WINDEF.H。定义如下:

             #define LOWORD(l)           ((WORD)(l))
             #define HIWORD(l)           ((WORD)(((DWORD)(l) >> 16) & 0xFFFF))

             hitPoint.x = LOWORD(lParam);
            hitPoint.y = HIWORD(lParam);
保存完坐标后我们设标志MouseClick为TRUE,这是在处理WM_PAINT时用来判断是否有鼠标左键按下消息。然后我们调用InvalidateRect()函数迫使WINDOWS重新绘制客户区。

           if(MouseClick)
            {
                TextOut(hDC,hitPoint.x,hitPoint.y,szCaptionMain,lstrlen(szCaptionMain));
            }

绘制客户区的代码首先检测MouseClick标志位,再决定是否重绘。因为我们在首次显示窗口时还没有左键按下的消息,所以我们在初始时把该标志设为FALSE,告诉WINDOWS不要重绘客户区,当有左键按下的消息时,它会在鼠标按下的位置绘制字符串。注意在调用TextOut()函数时,其关于字符串长度的参数是调用lstrlen()函数来计算的。

相关网站:http://edu.
搜索更多相关主题的帖子: sdk windows 鼠标 输入 
2008-10-16 10:04
永久的守护
Rank: 1
等 级:新手上路
威 望:2
帖 子:425
专家分:6
注 册:2007-6-9
得分:0 
明显广告 但是还是小顶一下

见了便做做了便放下了了有何不了,慧生于觉觉生于自在生生还是无生。
活则生变,简而至稳。
2008-10-16 10:10
StarWing83
Rank: 8Rank: 8
来 自:仙女座大星云
等 级:贵宾
威 望:19
帖 子:3951
专家分:748
注 册:2007-11-16
得分:0 
广告?那要删不?给个建议?

专心编程………
飞燕算法初级群:3996098
我的Blog
2008-10-16 10:20



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-238580-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.021834 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved