您的位置:澳门新葡8455最新网站 > 澳门新葡8455最新网站 > 第十一天

第十一天

发布时间:2019-11-05 13:18编辑:澳门新葡8455最新网站浏览(188)

    CHECKE奥迪Q52程序包蕴叁个键盘接口,内容与CHECKE揽胜极光1完全相近。利用←、→、↑、↓四个方向键能够在二十多个矩形之间活动鼠标指针。Home键把鼠标指针移动到左上角的矩形;End键使鼠标指针落到右下角的矩形。空格键和回车键都能够切换X形标志。

    C语言Windows程序设计 -> 第十三日 -> 使用鼠标

     

    鼠标的使用相近是通过拿到Windows鼠标新闻来赢得客户前段时间的鼠标状态的。

    风姿浪漫、鼠标的介绍
        鼠标是计算机的输入设备之风度翩翩, 在图形化的操作系统上, 鼠标的利用使一些目不暇接的操作变得简单, 随着科技(science and technology)的升华, 鼠标的连串也愈扩展, 按接口类型可分为串行鼠标、PS/2鼠标、总线鼠标、USB鼠标(多为光电鼠标卡塔尔国多样。按其行事原理及其内部结构的两样足以分成机械式,光机式和光电式。
        
        这里大家不研商鼠标的硬件构造, 更加多关于鼠标的硬件知识请自行查阅有关质地。
        
        1>. 鼠标所在的岗位
            在Windows系统下, 客商移动鼠标时, 在显示屏上雷同会以三个斜式的箭头来代表鼠标当前的职位, 这几个箭头实际上是三个位图格式的小Logo, 称为"鼠标指针", 鼠标指针具有贰个单像素精度的"热销"(hot spot), 当鼠标样式为箭头时, 那么些"紧俏"正是鼠标箭头的尖峰, 还也是有局地样式是"十"字样式, 那样的指针"销路广"位于"十"字的大旨地方, 火热在展现设备上提示了二个准儿的义务。 当大家去捕获鼠标指针的职位时, 实际上是指鼠标指针的那么些"热门"所在的像素单元的岗位。
        
        2>. 鼠标的术语
            ①. 单击 : 按下鼠标按钮, 然后松手;
            ②. 双击 : 延续快速的按下鼠标同二个开关然后松手;
            ③. 拖动 : 保持开关按下情状, 并移动鼠标。
            
            以后大家广大的三键鼠标, 多少个开关分布称为左键、中键和右键, 个中左键的标志符简写为LBUTTON, 中键的标识符为MBUTTON, 右键的标志符为RBUTTON。 双键鼠标唯有左键和右键, 单键鼠标唯有左键。
            
        3>. 鼠标的体裁
            Windows系统为鼠标提供了两种暗许的鼠标准样本式, 如: 箭头、沙漏、十字照准等, 在这里前学习的长河中其实我们早就触发了运用默许的鼠标样式, 回想那行代码:

            wndclass.hCursor = LoadCursor( NULL, IDC_ARROW ) ;
    

            这样正是应用多个暗中认可的斜式箭头作为鼠标的指针样式, 斜式箭头样式的标志符为 IDC_ARROW, 那几个标记符定义在 WINUSER.H 头文件中, 别的还或者有以下标记符及其对应的样式:

    澳门新葡8455最新网站 1

    二、使用鼠标的简单示例
        1>. 示例一: 获取鼠标指针地方
            在此个示例中示范如何获取鼠标的地点, 先说下有关的新闻标志符以至函数。
            音讯标记符: WM_MOUSEMOVE 当鼠标指针在客商区内活动或鼠标指针经过顾客区窗口时会得到这么些音信。
            获取鼠标地方的函数: GetCursorPos 该函数的原型: BOOL GetCursorPos(LPPOINT lpPoint) ;
            代码片段:

     1     switch(message)   2     {   3     case WM_PAINT:        //处理重绘消息   4         hdc = BeginPaint( hwnd, &ps ) ;   5         wsprintf( szBuffer,  "屏幕坐标:(%i, %i)", pt.x, pt.y );   6         TextOut( hdc, 10, 10, szBuffer, lstrlen(szBuffer) ) ;   7         ScreenToClient( hwnd, &pt ) ;        //将相对于屏幕的坐标转换为相对于窗口客户区的坐标   8         wsprintf( szBuffer,  "客户区坐标:(%i, %i)", pt.x, pt.y );   9         TextOut( hdc, 10, 30, szBuffer, lstrlen(szBuffer) ) ;  10         EndPaint( hwnd, &ps ) ;  11         return 0 ;  12   13     case WM_MOUSEMOVE:        //处理鼠标移动时发来的消息  14         GetCursorPos(&pt) ;  15         InvalidateRect( hwnd, NULL, TRUE ) ;  16         return 0 ;
    

        完整的言传身教代码:

    澳门新葡8455最新网站 2澳门新葡8455最新网站 3View Code - GetCursorPosition

     1 #include<windows.h>   2    3 LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM ) ;   4    5 int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow )   6 {   7     static TCHAR szAppName[] = TEXT( "UseMouse_Demo" ) ;   8     HWND hwnd ;   9     MSG msg ;  10     WNDCLASS wndclass ;  11   12     wndclass.hInstance        = hInstance ;  13     wndclass.lpfnWndProc    = WndProc ;  14     wndclass.lpszClassName    = szAppName ;  15     wndclass.style            = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS ;  16     wndclass.hbrBackground    = (HBRUSH) GetStockObject( WHITE_BRUSH ) ;  17     wndclass.hCursor        = LoadCursor( NULL, IDC_ARROW ) ;  18     wndclass.hIcon            = LoadIcon( NULL, IDI_APPLICATION ) ;  19     wndclass.cbClsExtra        = 0 ;  20     wndclass.cbWndExtra        = 0 ;  21     wndclass.lpszMenuName    = 0 ;  22   23     if( !RegisterClass(&wndclass) )  24     {  25         MessageBox( NULL, TEXT("错误, 无法注册窗口类."), TEXT("错误"), MB_OK ) ;  26         return 0 ;  27     }  28   29     hwnd = CreateWindow( szAppName, TEXT("获取鼠标指针位置 - Demo"),  30         WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,  31         CW_USEDEFAULT, CW_USEDEFAULT,  32         NULL, NULL, hInstance, NULL ) ;  33   34     ShowWindow( hwnd, iCmdShow ) ;  35     UpdateWindow( hwnd ) ;  36   37     while( GetMessage(&msg, NULL, 0, 0) )  38     {  39         TranslateMessage( &msg ) ;  40         DispatchMessage( &msg ) ;  41     }  42   43     return msg.wParam ;  44 }  45   46 LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )  47 {  48     HDC hdc ;  49     PAINTSTRUCT ps ;  50     static POINT pt ;  51     TCHAR szBuffer[128] ;  52   53     switch(message)  54     {  55     case WM_PAINT:  56         hdc = BeginPaint( hwnd, &ps ) ;  57         wsprintf( szBuffer,  "屏幕坐标:(%i, %i)", pt.x, pt.y );  58         TextOut( hdc, 10, 10, szBuffer, lstrlen(szBuffer) ) ;  59         ScreenToClient( hwnd, &pt ) ;  60         wsprintf( szBuffer,  "客户区坐标:(%i, %i)", pt.x, pt.y );  61         TextOut( hdc, 10, 30, szBuffer, lstrlen(szBuffer) ) ;  62         EndPaint( hwnd, &ps ) ;  63         return 0 ;  64   65     case WM_MOUSEMOVE:  66         GetCursorPos(&pt) ;  67         InvalidateRect( hwnd, NULL, TRUE ) ;  68         return 0 ;  69   70     case WM_DESTROY:  71         PostQuitMessage(0) ;  72         return 0 ;  73     }  74   75     return DefWindowProc( hwnd, message, wParam, lParam ) ;  76 }
    

            说一下总体的思绪, 要即时追踪获取鼠标在荧屏中的坐标, 首先要捕获鼠标的移位音讯 WM_MOUSEMOVE, 当Windows向我们发来以此音讯时就代码鼠标在伸开运动, 随后我们对这几个鼠标移动音讯举行处理, 调用 GetCursorPos(&pt) ; 这些函数获取鼠标今后之处, 获取到鼠标地方后为了能够登时在窗口中显示出来, 再调用 InvalidateRect( hwnd, NULL, TRUE ) ; 使任何客商区形成无效状态, 进而引发 WM_PAINT 必要重绘客户区内容的消息, 在拍卖重绘音信时输出刚刚收获的鼠标指针坐标地点。
            
            关于 ScreenToClient( hwnd, &pt ) ; :
                这一个函数的效应是将显示屏坐标(绝对于整个显示器左上角的坐标)转变到相对于窗口客户区的坐标, 荧屏坐标与窗口顾客区坐标的意义如图所示:

    澳门新葡8455最新网站 4

                GetCursorPos拿到的鼠标地点是荧屏坐标, 假设想知道她在窗口客商区内的相对地方就必要调用ScreenToClient函数将其转会为客商区坐标。
              其他还应该有三个WIndows函数是将窗口顾客区坐标转成显示屏坐标的, 函数为: ClientToScreen( hwnd, &pt ) ;
              获取鼠标指针的岗位还会有其余的办法, 这里只是此中的一种。
        
        
        2>. 示例二: 管理鼠标左键单击事件
            鼠标左键在客商区被单击时发来的音信: WM_LBUTTONDOWN

     1     switch(message)   2     {   3     case WM_PAINT:   4         hdc = BeginPaint( hwnd, &ps ) ;   5         EndPaint( hwnd, &ps ) ;   6         return 0 ;   7    8     case WM_LBUTTONDOWN:    //处理鼠标左键单击被按下时产生的消息   9         x = LOWORD( lParam ) ;    //获取鼠标位置x坐标信息  10         y = HIWORD( lParam ) ;    //获取鼠标位置y坐标信息  11         wsprintf( szBuffer,  "鼠标左键被单击, 击中位置: (%i, %i)", x, y );  12         MessageBox( hwnd, szBuffer, TEXT("鼠标动作"), MB_OK ) ;  13         return 0 ;  14   15     case WM_DESTROY:  16         PostQuitMessage(0) ;  17         return 0 ;  18     }
    

        完整的示范代码:

    澳门新葡8455最新网站 5澳门新葡8455最新网站 6View Code - WM_LBUTTONDOWN

     1 #include<windows.h>   2    3 LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM ) ;   4    5 int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow )   6 {   7     static TCHAR szAppName[] = TEXT( "UseMouse_Demo" ) ;   8     HWND hwnd ;   9     MSG msg ;  10     WNDCLASS wndclass ;  11   12     wndclass.hInstance        = hInstance ;  13     wndclass.lpfnWndProc    = WndProc ;  14     wndclass.lpszClassName    = szAppName ;  15     wndclass.style            = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS ;  16     wndclass.hbrBackground    = (HBRUSH) GetStockObject( WHITE_BRUSH ) ;  17     wndclass.hCursor        = LoadCursor( NULL, IDC_ARROW ) ;  18     wndclass.hIcon            = LoadIcon( NULL, IDI_APPLICATION ) ;  19     wndclass.cbClsExtra        = 0 ;  20     wndclass.cbWndExtra        = 0 ;  21     wndclass.lpszMenuName    = 0 ;  22   23     if( !RegisterClass(&wndclass) )  24     {  25         MessageBox( NULL, TEXT("错误, 无法注册窗口类."), TEXT("错误"), MB_OK ) ;  26         return 0 ;  27     }  28   29     hwnd = CreateWindow( szAppName, TEXT("处理鼠标单击事件 - Demo"),  30         WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,  31         CW_USEDEFAULT, CW_USEDEFAULT,  32         NULL, NULL, hInstance, NULL ) ;  33   34     ShowWindow( hwnd, iCmdShow ) ;  35     UpdateWindow( hwnd ) ;  36   37     while( GetMessage(&msg, NULL, 0, 0) )  38     {  39         TranslateMessage( &msg ) ;  40         DispatchMessage( &msg ) ;  41     }  42   43     return msg.wParam ;  44 }  45   46 LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )  47 {  48     HDC hdc ;  49     PAINTSTRUCT ps ;  50     static POINT pt ;  51     TCHAR szBuffer[128] ;  52     static int x, y ;  53   54     switch(message)  55     {  56     case WM_PAINT:  57         hdc = BeginPaint( hwnd, &ps ) ;  58         EndPaint( hwnd, &ps ) ;  59         return 0 ;  60   61     case WM_LBUTTONDOWN:  62         x = LOWORD( lParam ) ;  63         y = HIWORD( lParam ) ;  64         wsprintf( szBuffer,  "鼠标左键被单击, 击中位置: (%i, %i)", x, y );  65         MessageBox( hwnd, szBuffer, TEXT("鼠标动作"), MB_OK ) ;  66         return 0 ;  67   68     case WM_DESTROY:  69         PostQuitMessage(0) ;  70         return 0 ;  71     }  72   73     return DefWindowProc( hwnd, message, wParam, lParam ) ;  74 }
    

        那一个示例演示的是当鼠标在客商区按下时弹出一个对话框, 对话框的从头到尾的经过是鼠标被按下时鼠标指针的职责音信, 能够看来, 这里我们平昔不应用 GetCursorPos 函数来收获鼠标指针的岗位, 而是通过

            x = LOWORD( lParam ) ;    //获取鼠标位置x坐标信息          y = HIWORD( lParam ) ;    //获取鼠标位置y坐标信息
    

        来获得的, 参数lParam包括了鼠标指针的职位新闻, 在那之中未有字节表示x坐标, 高位字节表示y坐标, 利用LOWORDHIWORD宏能够获取这个坐标值, 这里得到的坐标指的是相对于窗口顾客区的坐标。

     

    三、客商区鼠标音讯
        与键盘新闻分歧, 在键盘新闻中, Windows只把键盘音讯发送到当前具备输入核心的窗口, 而鼠标新闻无论窗口是还是不是获得关节, 只要鼠标经过顾客区, 只怕在客商区内被单击窗口进程都会收到鼠标音讯, 被点击(包含双击/单击/拖动)的窗口将成为活动窗口。与客商区新闻相对应的叫做非客商区消息, 非客商区消息是指鼠标指针在窗口内并在在顾客区外的活动或单击/双击等, 非顾客区包蕴窗口的标题栏、菜单栏、滚动条、窗口的边框, 这么些将要末端举行研商, 这里先说客商区鼠标音讯。
        
        1>. 鼠标单击
            鼠标在顾客区单击时各样鼠标开关所发出的音信如下:

    鼠标按键 按下时产生的消息 释放时产生的消息
    左键 WM_LBUTTONDOWN WM_LBUTTONUP
    中键 WM_MBUTTONDOWN WM_MBUTTONUP
    右键 WM_RBUTTONDOWN WM_RBUTTONUP

                     

     

     

        示例第22中学早就演示了三个甩卖鼠标左键单击的示范, 对于中键和右键处理的点子是生机勃勃致的, 只要等待Windows发来音讯然后管理那些新闻就可以了。
            
        2>. wParam参数中的内容
            参数wParam中的值表示了鼠标按键、Shift键和Ctrl键的状态。 将wParam与"鼠标键"标记符实行按位与(&)运算可以收获鼠标开关与鼠标键的动静, 从前缀MK_为开始的标识符称为"鼠标键", 有如下鼠标键:

                #define MK_LBUTTON          0x0001            //按下左键              #define MK_RBUTTON          0x0002            //按下右键
                #define MK_MBUTTON          0x0010            //按下中键              #define MK_SHIFT            0x0004            //按下Shift键              #define MK_CONTROL          0x0008            //按下Ctrl键  
    

            比方, 当选拔到 WM_LBUTTONDOWN 消息时, 若

                wParam & MK_SHIFT 
    

            的值为TRUE(非零), 则表示按下左键的同一时间也按下了Shift键。
            例如:

            case WM_LBUTTONDOWN:              if( wParam & MK_CONTROL )              {                  MessageBox( hwnd, TEXT("Ctrl键与鼠标左键同时被按下!"), TEXT("鼠标动作"), MB_OK ) ;                  return 0 ;              }              return 0 ;
    

            唯有当鼠标左键与键盘的Ctrl键同有难题间被按下时大家弹出个对话框表达"Ctrl键与鼠标左键同有时候被按下!", 不然什么也不做。
            
            3>. 鼠标双击
                双击对五回击中的地点以致时光间隔都有应当必要, 只有当三次快捷的单击在情理地方上靠的超近况且时间隔开超短的动静下才算双击。
                
                借使想让窗口进度选取鼠标双击音讯, 要求在登记窗口类(RegisterClass)时, 最早化wndclass中的style成员的质量中再加上CS_DBLCLKS标识符:

                    wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS ;
    

                若是在窗口类的style成员中从未满含 CS_DBLCLKS 标志符, 那么尽管当客户双击时不会发出双击新闻, 而是发生风华正茂串如下的信息:

                    WM_LBUTTONDOWN                  WM_LBUTTONUP                  WM_LBUTTONDOWN                  WM_LBUTTONUP
    

                由于客户在三回九转三遍按下鼠标左键时索要自然时间, 即便这些时间非常的短暂, 可是在这里个历程中前后相继照旧有希望选取任何音讯的, 例如客户在赶快的四回单击中手的稍稍抖动就能在中间插入一个WM_MOUSEMOVE的音讯, 这里临时忽视当中插入的信息, 要是消息就是三翻五次的那一个。
                
    澳门新葡8455最新网站,            当窗口类的style成员只中饱含CS_DBLCLKS标记符后, 客户再一次双击就能够爆发如此的后生可畏串消息:

                    WM_LBUTTONDOWN                  WM_LBUTTONUP                  WM_LBUTTONDBLCLK                  WM_LBUTTONUP
    

                能够看见, 在加盟 CS_DBLCLKS 标志符后, 第七个音信 WM_LBUTTONDOWN 只是被归纳的替换来了 WM_LBUTTONDBLCLK 消息。
                
                鼠标各样开关双击时第多个新闻所对应替换的新闻如下:

                #define WM_LBUTTONDBLCLK                0x0203            //左键              #define WM_MBUTTONDBLCLK                0x0209            //中键              #define WM_RBUTTONDBLCLK                0x0206            //右键
    

     

    四、非顾客区鼠标音信
        非顾客区新闻差不离与客商区音信完全对应, 只是在标志符中多了一个"NC"字符(noclient), 当鼠标指针在窗口的非顾客区移动时(比方标题栏), 窗口进度就能够采用到 WM_NCMOUSEMOVE 新闻, 在客商区外鼠标按下发出的消息如下:

    鼠标按键 按下 释放 第二次按下(双击)
    左键 WM_NCLBUTTONDWON WM_NCLBUTTONUP WM_NCLBUTTONDBLCLK
    中键 WM_NCMBUTTONDOWN WM_NCMBUTTONUP WM_NCMBUTTONDBLCLK
    右键 WM_NCRBUTTONDOWN WM_NCRBUTTONUP WM_NCRBUTTONDBLCLK

     

     

     

      别的与客商区音讯分裂的是, 这里的 wParam 参数中的值与客商区中的含义有所分裂, 这里的 wParam 表示非客商区鼠标移动或单击的职分, 他的值被设定成一些以 HT 开首的标志符中, 表示 "猜中测量试验"(Hit Test), 关于击中测量试验与以HT起先的标志符就要下边讲到。
        
        参数 lParam 中的值依旧是鼠标指针的岗位音信, 但那时的新闻恰好与顾客区中的 lParam 的坐标消息相反, 顾客区中的 lParam 的值是相对于窗口顾客区的坐标, 而这里的(非客商区) lParam 中所包括的坐标新闻是显示器坐标, 在地点已经涉嫌过, 使用ScreenToClientClientToScreen能够完毕荧屏坐标与客商区坐标之间的转账。
        
        管理非客商区左键单击示例:

        switch(message)      {      case WM_PAINT:          hdc = BeginPaint( hwnd, &ps ) ;          EndPaint( hwnd, &ps ) ;          return 0 ;        case WM_NCLBUTTONDOWN:        //处理非客户区鼠标左键单击事件          MessageBox( hwnd, TEXT("非客户区鼠标左键被单击"), TEXT("鼠标动作"), MB_OK ) ;          return 0 ;        case WM_DESTROY:          PostQuitMessage(0) ;          return 0 ;      }
    

     

    五、关于"击中测量检验"新闻 WM_NCHITTEST
        WM_NCHITTEST表示"非顾客区击中测验", 所谓的命中测验正是测量检验鼠标当前所在的职位, 那个消息的优先级高于此外具备的客商区和非顾客区消息, 参数 lParam 中含有相对于荧屏坐标的x值与y值, wParam 参数另有用场。
        
        日常的话, WM_NCHITTEST 音信是付诸 DefWindowProc 默许的音讯管理函数实行拍卖的, 对于顾客区中, Windows会利用 WM_NCHITTEST 新闻来产生负有和任何鼠标地点相关的鼠标新闻。对于非顾客区信息以来, DefWindowProc 管理 WM_NCHITTEST 音讯后重临八个 wParam 值, 这几个值能够是不管三七四十风流倜傥贰个非顾客区鼠标新闻的 wParam 参数的值, 那么些 wParam 值用来决断鼠标的四面八方的职位。
        
        举个例子来说, 借使 DefWindowProc 函数在管理 WM_NCHITTEST 新闻后回去多少个 HTCLIENT , One plusLIENT 表示鼠标在顾客区, 当时Windows会将显示屏坐标转变到客商区坐标,并发生三个相关的客户区的鼠标音讯;
        当再次回到值为 HTCAPTION 表示鼠标那时在二个标题栏中, 所以Windows会将那个时候鼠标的坐标地方转成显示器坐标并发送有关的非顾客区音信。
        
        那么些重临的标志符定义在WINUSER.H头文件中, 相关的概念如下:

    #define HTERROR             (-2)                    //在屏幕的后面或在窗体之间的线上(使函数DefWindowProc产生一个警示音)  #define HTTRANSPARENT       (-1)                    //在一个被其它窗口覆盖的窗口中  #define HTNOWHERE           0                        //在屏幕背景或窗口之间的分界线  #define HTCLIENT            1                        //在客户区中  #define HTCAPTION           2                        //在标题栏中  #define HTSYSMENU           3                        //在一个窗口菜单栏或子窗口的关闭按钮上  #define HTGROWBOX           4                        //在尺寸框中  #define HTSIZE              HTGROWBOX                //同HTGROWBOX  #define HTMENU              5                        //在菜单区域  #define HTHSCROLL           6                        //在水平滚动条上  #define HTVSCROLL           7                        //在垂直滚动条上  #define HTMINBUTTON         8                        //在最小化按钮上  #define HTMAXBUTTON         9                        //在最大化按钮上  #define HTLEFT              10                        //在窗口的左边框上  #define HTRIGHT             11                        //在窗口的右边框上  #define HTTOP               12                        //在窗口水平边框的上方  #define HTTOPLEFT           13                        //在窗口边框的左上角  #define HTTOPRIGHT          14                        //在窗口边框的右上角  #define HTBOTTOM            15                        //在窗口的水平边框的底部  #define HTBOTTOMLEFT        16                        //在窗口边框的左下角  #define HTBOTTOMRIGHT       17                        //在窗口边框的右下角  #define HTBORDER            18                        //在不具有可变大小边框的窗口的边框上  #define HTREDUCE            HTMINBUTTON                //同HTMINBUTTON  #define HTZOOM              HTMAXBUTTON                //同HTMAXBUTTON  #define HTSIZEFIRST         HTLEFT                    //同HTLEFT  #define HTSIZELAST          HTBOTTOMRIGHT             //同HTBOTTOMRIGHT  #define HTOBJECT            19                        //忽略该标识符, 已废弃  #define HTCLOSE             20                        //在关闭按钮上  #define HTHELP              21                        //在帮助按钮上
    

        这样在得到非客商区音信时大家就足以依赖 wParam 中的值推断鼠标在窗口之处了, 像那样:

        case WM_NCLBUTTONDOWN:        //处理非客户区的鼠标左键单击事件          x = LOWORD( lParam ) ;    //通过lParam获取鼠标位置          y = HIWORD( lParam ) ;          switch(wParam)            //通过wParam判断鼠标在窗口的位置          {          case HTCAPTION:        //在标题上              wsprintf( szBuffer,  "鼠标左键在标题栏中被单击, 击中位置: (%i, %i)", x, y ) ;              MessageBox( hwnd, szBuffer, TEXT("鼠标动作"), MB_OK ) ;              break ;          case HTMINBUTTON:    //在最小化按钮上              wsprintf( szBuffer,  "鼠标左键在最小化按钮上被单击, 击中位置: (%i, %i)", x, y ) ;              MessageBox( hwnd, szBuffer, TEXT("鼠标动作"), MB_OK ) ;              break ;          case HTMAXBUTTON:    //在最大化按钮上              wsprintf( szBuffer,  "鼠标左键在最大化按钮上被单击, 击中位置: (%i, %i)", x, y ) ;              MessageBox( hwnd, szBuffer, TEXT("鼠标动作"), MB_OK ) ;              break ;          }          return 0 ;
    

        首先捕获 鼠标左键在非顾客区的单击事件, 然后再经过 wParam 决断鼠标在窗口的职位, 这里收获鼠标地点是经过 LOWOXC90D 和 HIWO瑞鹰D 宏实现的, 还应该有多少个效能相通的宏也能够用来获得lParam中的鼠标新闻, 他们是 GET_X_LPARAM 宏和 GET_Y_LPARAM, 可是那多个宏是定义在 WINDOWSX.H 头文件中的, 借使要选取这八个宏供给将 WINDOWSX.H 满含进来。
        举例:

        xPos = GET_X_LPARAM(lParam) ;      yPos = GET_Y_LPARAM(lParam) ;
    

     

     


    wid, 2012.11.30

     

    上风度翩翩篇: C语言Windows程序设计 -> 第十天 -> 响应键盘事件

     


    澳门新葡8455最新网站 7澳门新葡8455最新网站 8

      1 /*---------------------------------------------
      2 CHECKER2.C -- Mouse Hit-Test Demo Program No.2
      3               (c) Charles Petzold, 1998
      4 ---------------------------------------------*/
      5 
      6 #include <Windows.h>
      7 
      8 #define DIVISIONS 5
      9 
     10 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
     11 
     12 int WINAPI WinMain( __in HINSTANCE hInstance
     13                     , __in_opt HINSTANCE hPrevInstance
     14                     , __in LPSTR lpCmdLine
     15                     , __in int nShowCmd )
     16 {
     17     static TCHAR szAppName[] = TEXT("Checker2");
     18     HWND hwnd;
     19     MSG msg;
     20     WNDCLASS wndclass;
     21 
     22     wndclass.style = CS_HREDRAW | CS_VREDRAW;
     23     wndclass.lpfnWndProc = WndProc;
     24     wndclass.cbClsExtra = 0;
     25     wndclass.cbWndExtra = 0;
     26     wndclass.hInstance = hInstance;
     27     wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
     28     wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
     29     wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
     30     wndclass.lpszMenuName = NULL;
     31     wndclass.lpszClassName = szAppName;
     32 
     33     if (!RegisterClass(&wndclass))
     34     {
     35         MessageBox(NULL, TEXT("Program requires Windows NT!")
     36             , szAppName, MB_ICONERROR);
     37         return 0;
     38     }
     39 
     40     hwnd = CreateWindow(szAppName, TEXT("Checker2 Mouse Hit-Test Demo")
     41         , WS_OVERLAPPEDWINDOW
     42         , CW_USEDEFAULT, CW_USEDEFAULT
     43         , CW_USEDEFAULT, CW_USEDEFAULT
     44         , NULL, NULL, hInstance, NULL);
     45 
     46     ShowWindow(hwnd, nShowCmd);
     47     UpdateWindow(hwnd);
     48 
     49     while (GetMessage(&msg, NULL, 0, 0))
     50     {
     51         TranslateMessage(&msg);
     52         DispatchMessage(&msg);
     53     }
     54 
     55     return msg.wParam;
     56 }
     57 
     58 LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
     59 {
     60     static BOOL fState[DIVISIONS][DIVISIONS];
     61     static int cxBlock, cyBlock;
     62     HDC hdc;
     63     int x, y;
     64     PAINTSTRUCT ps;
     65     POINT point;
     66     RECT rect;
     67 
     68     switch (message)
     69     {
     70     case WM_SIZE:
     71         cxBlock = LOWORD(lParam) / DIVISIONS;
     72         cyBlock = HIWORD(lParam) / DIVISIONS;
     73         return 0;
     74 
     75     case WM_SETFOCUS:
     76         ShowCursor(TRUE);
     77         return 0;
     78 
     79     case WM_KILLFOCUS:
     80         ShowCursor(FALSE);
     81         return 0;
     82 
     83     case WM_KEYDOWN:
     84         GetCursorPos(&point);
     85         ScreenToClient(hwnd, &point);
     86 
     87         x = max(0, min(DIVISIONS - 1, point.x / cxBlock));
     88         y = max(0, min(DIVISIONS - 1, point.y / cyBlock));
     89 
     90         switch (wParam)
     91         {
     92         case VK_UP:
     93             --y;
     94             break;
     95 
     96         case VK_DOWN:
     97             ++y;
     98             break;
     99 
    100         case VK_LEFT:
    101             --x;
    102             break;
    103 
    104         case VK_RIGHT:
    105             ++x;
    106             break;
    107 
    108         case VK_HOME:
    109             x = y = 0;
    110             break;
    111 
    112         case VK_END:
    113             x = y = DIVISIONS - 1;
    114             break;
    115 
    116         case VK_RETURN:
    117         case VK_SPACE:
    118             SendMessage(hwnd, WM_LBUTTONDOWN, MK_LBUTTON, MAKELONG(x * cxBlock, y * cyBlock));
    119             break;
    120         }
    121 
    122         x = (x + DIVISIONS) % DIVISIONS;
    123         y = (y + DIVISIONS) % DIVISIONS;
    124 
    125         point.x = x * cxBlock + cxBlock / 2;
    126         point.y = y * cyBlock + cyBlock / 2;
    127 
    128         ClientToScreen(hwnd, &point);
    129         SetCursorPos(point.x, point.y);
    130         return 0;
    131 
    132     case WM_LBUTTONDOWN:
    133         x = LOWORD(lParam) / cxBlock;
    134         y = HIWORD(lParam) / cyBlock;
    135 
    136         if (x < DIVISIONS && y < DIVISIONS)
    137         {
    138             fState[x][y] ^= 1;
    139 
    140             rect.left = x * cxBlock;
    141             rect.top = y * cyBlock;
    142             rect.right = (x + 1) * cxBlock;
    143             rect.bottom = (y + 1) * cyBlock;
    144 
    145             InvalidateRect(hwnd, &rect, FALSE);
    146         }
    147         else
    148             MessageBeep(0);
    149         return 0;
    150 
    151     case WM_PAINT:
    152         hdc = BeginPaint(hwnd, &ps);
    153 
    154         for (x = 0; x < DIVISIONS; ++x)
    155             for (y = 0; y < DIVISIONS; ++y)
    156             {
    157                 Rectangle(hdc, x * cxBlock, y * cyBlock
    158                     , (x + 1) * cxBlock, (y + 1) * cyBlock);
    159                 
    160                 if (fState[x][y])
    161                 {
    162                     MoveToEx(hdc, x * cxBlock, y * cyBlock, NULL);
    163                     LineTo(hdc, (x + 1) * cxBlock, (y + 1) * cyBlock);
    164                     MoveToEx(hdc, x * cxBlock, (y + 1) * cyBlock, NULL);
    165                     LineTo(hdc, (x + 1) * cxBlock, y * cyBlock);
    166                 }
    167             }
    168 
    169         EndPaint(hwnd, &ps);
    170         return 0;
    171 
    172     case WM_DESTROY:
    173         PostQuitMessage(0);
    174         return 0;
    175     }
    176 
    177     return DefWindowProc(hwnd, message, wParam, lParam);
    178 }
    

    CHECKER2.C

    在CHECKER2程序中,处理WM_KEYDOWN时利用GetCursorPos决断指针的岗位,并选取ScreenToClient将显示屏坐标转变到客商区坐标,然后将坐标值除以矩形块的宽和高,得到x和y。那个x和y的值表示了矩形在5*5数组中之处。当按下有个别键时,鼠标指针恐怕在客户区也可能不在顾客区内,由此x和y必得含有在min和max的宏管理中,有限扶持它们的限量处于0和4期间。

    对于方向键,CHECKEENVISION2程序相应的扩张或减弱x和y的值。若按下回车键或空格键,CHECKEOdyssey2程序调用SendMessage给协和发送叁个WM_LBUTTONDOWN消息。最后,WM_KEYDOWN管理逻辑总计得到针对性矩形中央的客户区坐标,并调用ClientToScreen将其调换成荧屏坐标,最终调用SetCursorPos设置指针的职位。

    本文由澳门新葡8455最新网站发布于澳门新葡8455最新网站,转载请注明出处:第十一天

    关键词:

上一篇:没有了

下一篇:没有了