VC驿站

 找回密码
 加入驿站

QQ登录

只需一步,快速开始

搜索
查看: 646|回复: 4

不懂就问,鼠标限制在窗口内移动

[复制链接]
35_avatar_middle
最佳答案
0 
online_vip 发表于 2019-4-19 10:04:21 | 显示全部楼层 |阅读模式
3驿站币
当鼠标在一个windows窗口上
左(或右)键点击进入窗口内
鼠标的光标消失
之后鼠标的所有操作(左右上下移动,左键右键,滚轮都限制在窗口内)
敢问一下大哥们
这怎么做到?

还有,进入窗口内后,怎么判断鼠标左右上下移动?移动了多少数值?
难道用WM_MOUSEMOVE之后保持之前的在窗口的坐标
然后相减?
还有什么更好的办法不?





上一篇:点击inf文件实现安装驱动的操作
下一篇:在win7里打印程序Spool32.exe 是否被spoolsv.exe
81_avatar_middle
最佳答案
3 
online_supermod 发表于 2019-4-19 11:11:34 | 显示全部楼层
隐藏光标的话可以使用 HideCaret,这个只是隐藏,实际上该怎么动还是怎么动,如果限制在窗口内的话,可以实时监测鼠标的位置是否在窗口内,不是的话就移动回来。暂时想到这么多,楼主可以试试
35_avatar_middle
最佳答案
0 
ico_lz  楼主| 发表于 2019-4-19 12:50:40 | 显示全部楼层
Debug 发表于 2019-4-19 11:11
隐藏光标的话可以使用 HideCaret,这个只是隐藏,实际上该怎么动还是怎么动,如果限制在窗口内的话,可以实 ...

这个功能和游戏窗口模式一个道理的
只是想知道有什么好方法能做到
95_avatar_middle
最佳答案
0 
在线会员 发表于 2019-4-19 16:33:55 | 显示全部楼层
本帖最后由 ET幻影 于 2019-4-19 16:40 编辑

限制鼠标可移动范围
BOOL ClipCursor(CONST RECT * lpRect)

设置/获取鼠标位置
BOOL GetCursorPos(LPPOINT lpPoint)
BOOL SetCursorPos(int X,int Y)

模拟鼠标操作
VOID mouse_event(
  DWORD     dwFlags,     // motion and click options
  DWORD     dx,          // horizontal position or change
  DWORD     dy,          // vertical position or change
  DWORD     dwData,      // wheel movement
  ULONG_PTR dwExtraInfo  // application-defined information
);
75_avatar_middle
最佳答案
0 
在线会员 发表于 2019-4-21 08:05:34 | 显示全部楼层
看看下面的directInput吧,它需要窗口,在win32窗口下做更好。在控制台下搞,显得代码有点多。不很方便。
directinput移动默认就是相对坐标,到屏幕边不动还会减或加,还在用力,体现力反馈。
代码同样粘贴到控制台程序即可。
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <strsafe.h>
using namespace std;
#define DIRECTINPUT_VERSION 0x0800
#include <dinput.h>
#pragma comment(lib, "dinput8.lib")
#pragma comment(lib, "dxguid.lib")
#include <process.h>
class CDInput{
        HRESULT hr;
        HWND  hWndParent;
        HBRUSH hbrBlack;
        BOOL boMode;
        BOOL boPress;
        LPDIRECTINPUT8 m_lpDI;
        LPDIRECTINPUTDEVICE8 m_lpKeyboard;
        LPDIRECTINPUTDEVICE8 m_lpMouse;
        DIMOUSESTATE2 m_MouseState;
        BYTE m_Keyboard[256];
        POINT m_pt;
public:
        HRESULT Init(HWND  hWnd);
        VOID GetInputData();
        void Leave();
};
class CWin32 {
        HWND hWndMain;
public:
    static BOOL boQuit;
    static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
                switch (message) {
                case WM_DESTROY: { PostQuitMessage(0);return 0; }
                case WM_ERASEBKGND:
                case WM_PAINT:return 0;
                }
        return DefWindowProc(hWnd,message,wParam,lParam);
    }
        int Go();
};
BOOL CWin32::boQuit = FALSE;

DWORD WINAPI Online(LPVOID lpParam) {
        CDInput input;
        input.Init((HWND)lpParam);
        while (!CWin32::boQuit) {
                input.GetInputData();
                SleepEx(1, TRUE);
        }
        input.Leave();
        return 0;
}

int main()
{
        cout << "按ESC键退出" << endl;
        cout << "按回车键切换鼠标协作方式" << endl;
        CWin32 app;
        return app.Go();
}
int CWin32::Go() {
        WNDCLASS wc={
           CS_HREDRAW | CS_VREDRAW,(WNDPROC)CWin32::WndProc,0,0,GetModuleHandle(NULL),
           LoadIcon(0, IDI_APPLICATION),LoadCursor(0, IDC_ARROW),
           0 ,0,TEXT("DInputClass")
        };
        RegisterClass(&wc);
        hWndMain = CreateWindowEx(WS_EX_TOPMOST,wc.lpszClassName,
                L"DInput示例",
                WS_OVERLAPPED | WS_CAPTION |WS_SYSMENU,
                CW_USEDEFAULT, CW_USEDEFAULT,400, 300,
                GetDesktopWindow(),
                0, wc.hInstance, NULL);
        UpdateWindow(hWndMain);
        ShowWindow(hWndMain, SW_SHOW);
        UINT ThreadId = 0;
        _beginthreadex(NULL, 0, (_beginthreadex_proc_type)Online, hWndMain, 0, &ThreadId);
        MSG msg;
        while (GetMessage(&msg, nullptr, 0, 0))
        {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
        }
        UnregisterClass(TEXT("DInputClass"), GetModuleHandle(NULL));
        boQuit = TRUE;
        cout << "延时等待线程退出" << endl;
        SleepEx(1000, TRUE);
        return msg.wParam;
}
VOID CDInput::GetInputData(){
        HWND foreground = GetForegroundWindow();
        bool visible = IsWindowVisible(foreground) != 0;
        if (foreground != hWndParent || !visible)
        {
                ZeroMemory(&m_MouseState,sizeof(DIMOUSESTATE2));
                ZeroMemory(m_Keyboard, sizeof(m_Keyboard));
        }
        else
        {
                hr=m_lpMouse->Acquire();
                hr=m_lpMouse->GetDeviceState(sizeof(DIMOUSESTATE2), &m_MouseState);
                hr=m_lpKeyboard->Acquire();
                hr=m_lpKeyboard->GetDeviceState(sizeof(m_Keyboard), m_Keyboard);
        }
        if (m_Keyboard[DIK_ESCAPE]&0x80) {
                SendMessage(hWndParent, WM_CLOSE, 0, 0);
                CWin32::boQuit = TRUE;
                return;
        }
        if (m_Keyboard[DIK_RETURN] & 0x80) {
                if(!boPress){
                        boMode = !boMode;
                        if (boMode) {
                                cout << "鼠标进入窗口独占方式:不响应任何窗口消息" << endl;
                                m_lpMouse->Release();
                                hr = m_lpDI->CreateDevice(GUID_SysMouse, &m_lpMouse, nullptr);
                                if (SUCCEEDED(hr)) {
                                        hr = m_lpMouse->SetDataFormat(&c_dfDIMouse2);
                                        hr = m_lpMouse->SetCooperativeLevel(hWndParent, DISCL_FOREGROUND | DISCL_EXCLUSIVE);
                                        //限制光标出窗口,不限制也行,移到窗口都不响应窗口消息,窗口外假死状态
                                        RECT rc;
                                        GetClientRect(hWndParent, &rc);
                                        ClientToScreen(hWndParent,(LPPOINT)&rc);
                                        ClientToScreen(hWndParent, (LPPOINT)&rc.right);
                                        ClipCursor(&rc);
                                }
                        }
                        else {
                                cout << "鼠标进入窗口共享方式:可操作任何窗口" << endl;
                                m_lpMouse->Release();
                                hr = m_lpDI->CreateDevice(GUID_SysMouse, &m_lpMouse, nullptr);
                                if (SUCCEEDED(hr)) {
                                        hr = m_lpMouse->SetDataFormat(&c_dfDIMouse2);
                                        hr = m_lpMouse->SetCooperativeLevel(hWndParent, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
                                        ClipCursor(NULL);
                                }
                        }       
                        boPress = TRUE;
                }
        }
        else boPress = FALSE;

        m_pt.x += m_MouseState.lX;
        m_pt.y += m_MouseState.lY;

        POINT spt,cpt;
        GetCursorPos(&spt);
        cpt = spt;
        ScreenToClient(hWndParent, &cpt);
        TCHAR  msg[MAX_PATH];
        StringCchPrintf(msg,MAX_PATH,
                L"鼠标相对坐标:1X=%d,1Y=%d,1Z=%d \n鼠标相对坐标累计:x=%d,y=%d \n"
                L"屏幕坐标x=%d,y=%d\n窗口客户区坐标x=%d,y=%d\n",
                m_MouseState.lX,
                m_MouseState.lY,
                m_MouseState.lZ,
                m_pt.x,
                m_pt.y,
                spt.x,
                spt.y,
                cpt.x,
                cpt.y
        );
        if (m_MouseState.rgbButtons[0] & 0x80)        StringCchCat(msg, MAX_PATH, L"左键按下");
        if (m_MouseState.rgbButtons[1] & 0x80)        StringCchCat(msg, MAX_PATH, L"右键按下");
        if (m_MouseState.rgbButtons[2] & 0x80)        StringCchCat(msg, MAX_PATH, L"中键按下");
        for (int i = 0;i < 255;i++) {
                if (m_Keyboard[i] & 0x80) {
                        TCHAR key[50];
                        StringCbPrintf(key,50,L"\n键=%d 值=%x", i, m_Keyboard[i]);
                        StringCchCat(msg, MAX_PATH, key);
                }
        }
        RECT rc;
        GetClientRect(hWndParent, &rc);
        HDC hdc = GetDC(hWndParent);
        FillRect(hdc, &rc, hbrBlack);
        SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT));
        SetTextColor(hdc, RGB(255,255, 0));
        SetBkColor(hdc, RGB(0, 0, 255));
        DrawText(hdc, msg, lstrlen(msg), &rc, DT_LEFT);
        ReleaseDC(hWndParent, hdc);

    return ;
}

HRESULT CDInput::Init(HWND  hWnd){
        hWndParent = hWnd;
        boMode = FALSE;
        boPress = FALSE;
        hr = DirectInput8Create(GetModuleHandle(nullptr), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&m_lpDI, nullptr);
        if (FAILED(hr)) return hr;
        //键盘
        hr = m_lpDI->CreateDevice(GUID_SysKeyboard, &m_lpKeyboard, nullptr);
        if (SUCCEEDED(hr)) {
                hr = m_lpKeyboard->SetDataFormat(&c_dfDIKeyboard);
                hr = m_lpKeyboard->SetCooperativeLevel(hWndParent, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
                DIPROPDWORD dipdw;
                dipdw.diph.dwSize = sizeof(DIPROPDWORD);
                dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
                dipdw.diph.dwObj = 0;
                dipdw.diph.dwHow = DIPH_DEVICE;
                dipdw.dwData = 10;
                hr = m_lpKeyboard->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph);
        }
        //鼠标
        hr = m_lpDI->CreateDevice(GUID_SysMouse, &m_lpMouse, nullptr);
        if (SUCCEEDED(hr)) {
                hr = m_lpMouse->SetDataFormat(&c_dfDIMouse2);
                hr = m_lpMouse->SetCooperativeLevel(hWndParent, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
        }
        ZeroMemory(&m_MouseState, sizeof(DIMOUSESTATE2));
        ZeroMemory(m_Keyboard, sizeof(m_Keyboard));

        GetCursorPos(&m_pt);
        hbrBlack = CreateSolidBrush(RGB(0, 0, 0));

        return hr;
}
void CDInput::Leave() {
        m_lpMouse->Release();
        m_lpKeyboard->Release();
        m_lpDI->Release();
        DeleteObject(hbrBlack);
}


不懂就问,鼠标限制在窗口内移动



您需要登录后才可以回帖 登录 | 加入驿站 qq_login

本版积分规则

×【发帖 友情提示】
1、请回复有意义的内容,请勿恶意灌水;
2、纯数字、字母、表情等无意义的内容系统将自动删除;
3、若正常回复后帖子被自动删除,为系统误删的情况,请重新回复其他正常内容或等待管理员审核通过后会自动发布;
4、感谢您对VC驿站一如既往的支持,谢谢合作!

关闭

站长提醒上一条 /2 下一条

QQ|小黑屋|手机版|VC驿站 ( 辽ICP备09019393号 )|网站地图wx_jqr

GMT+8, 2020-11-27 10:57

Powered by CcTry.CoM

© 2009-2020 cctry.com

快速回复 返回顶部 返回列表