Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Clark Lin
StudyDx
Commits
d14dac18
Commit
d14dac18
authored
Dec 17, 2022
by
Clark Lin
Browse files
add mouse event handle
parent
ac85e129
Changes
7
Hide whitespace changes
Inline
Side-by-side
StudyDx/Keyboard.h
View file @
d14dac18
...
...
@@ -38,7 +38,7 @@ public:
Type
type
;
unsigned
char
code
;
public:
Event
()
Event
()
noexcept
:
type
(
Type
::
Invalid
),
code
(
0u
)
...
...
StudyDx/Mouse.cpp
0 → 100644
View file @
d14dac18
/******************************************************************************************
* Chili DirectX Framework Version 16.07.20 *
* Mouse.cpp *
* Copyright 2016 PlanetChili <http://www.planetchili.net> *
* *
* This file is part of The Chili DirectX Framework. *
* *
* The Chili DirectX Framework is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* The Chili DirectX Framework is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with The Chili DirectX Framework. If not, see <http://www.gnu.org/licenses/>. *
******************************************************************************************/
#include "Mouse.h"
#include "Window.h"
std
::
pair
<
int
,
int
>
Mouse
::
GetPos
()
const
noexcept
{
return
{
x
,
y
};
}
int
Mouse
::
GetPosX
()
const
noexcept
{
return
x
;
}
int
Mouse
::
GetPosY
()
const
noexcept
{
return
y
;
}
bool
Mouse
::
IsInWindow
()
const
noexcept
{
return
isInWindow
;
}
bool
Mouse
::
LeftIsPressed
()
const
noexcept
{
return
leftIsPressed
;
}
bool
Mouse
::
RightIsPressed
()
const
noexcept
{
return
rightIsPressed
;
}
Mouse
::
Event
Mouse
::
Read
()
noexcept
{
if
(
buffer
.
size
()
>
0u
)
{
Mouse
::
Event
e
=
buffer
.
front
();
buffer
.
pop
();
return
e
;
}
else
{
return
Mouse
::
Event
();
}
}
void
Mouse
::
Flush
()
noexcept
{
buffer
=
std
::
queue
<
Event
>
();
}
void
Mouse
::
OnMouseMove
(
int
newx
,
int
newy
)
noexcept
{
x
=
newx
;
y
=
newy
;
buffer
.
push
(
Mouse
::
Event
(
Mouse
::
Event
::
Type
::
Move
,
*
this
)
);
TrimBuffer
();
}
void
Mouse
::
OnMouseEnter
()
noexcept
{
isInWindow
=
true
;
buffer
.
push
(
Mouse
::
Event
(
Mouse
::
Event
::
Type
::
Enter
,
*
this
));
TrimBuffer
();
}
void
Mouse
::
OnMouseLeave
()
noexcept
{
isInWindow
=
false
;
buffer
.
push
(
Mouse
::
Event
(
Mouse
::
Event
::
Type
::
Leave
,
*
this
));
TrimBuffer
();
}
void
Mouse
::
OnLeftPressed
(
int
x
,
int
y
)
noexcept
{
leftIsPressed
=
true
;
buffer
.
push
(
Mouse
::
Event
(
Mouse
::
Event
::
Type
::
LPress
,
*
this
)
);
TrimBuffer
();
}
void
Mouse
::
OnLeftReleased
(
int
x
,
int
y
)
noexcept
{
leftIsPressed
=
false
;
buffer
.
push
(
Mouse
::
Event
(
Mouse
::
Event
::
Type
::
LRelease
,
*
this
)
);
TrimBuffer
();
}
void
Mouse
::
OnRightPressed
(
int
x
,
int
y
)
noexcept
{
rightIsPressed
=
true
;
buffer
.
push
(
Mouse
::
Event
(
Mouse
::
Event
::
Type
::
RPress
,
*
this
)
);
TrimBuffer
();
}
void
Mouse
::
OnRightReleased
(
int
x
,
int
y
)
noexcept
{
rightIsPressed
=
false
;
buffer
.
push
(
Mouse
::
Event
(
Mouse
::
Event
::
Type
::
RRelease
,
*
this
)
);
TrimBuffer
();
}
void
Mouse
::
OnWheelUp
(
int
x
,
int
y
)
noexcept
{
buffer
.
push
(
Mouse
::
Event
(
Mouse
::
Event
::
Type
::
WheelUp
,
*
this
)
);
TrimBuffer
();
}
void
Mouse
::
OnWheelDown
(
int
x
,
int
y
)
noexcept
{
buffer
.
push
(
Mouse
::
Event
(
Mouse
::
Event
::
Type
::
WheelDown
,
*
this
)
);
TrimBuffer
();
}
void
Mouse
::
TrimBuffer
()
noexcept
{
while
(
buffer
.
size
()
>
bufferSize
)
{
buffer
.
pop
();
}
}
void
Mouse
::
OnWheelDelta
(
int
x
,
int
y
,
int
delta
)
noexcept
{
wheelDeltaCarry
+=
delta
;
// generate events for every 120
// 默认每次达到120,执行一次滚轮事件。如果数字够大,可以执行复数次
while
(
wheelDeltaCarry
>=
WHEEL_DELTA
)
{
wheelDeltaCarry
-=
WHEEL_DELTA
;
OnWheelUp
(
x
,
y
);
}
while
(
wheelDeltaCarry
<=
-
WHEEL_DELTA
)
{
wheelDeltaCarry
+=
WHEEL_DELTA
;
OnWheelDown
(
x
,
y
);
}
}
\ No newline at end of file
StudyDx/Mouse.h
0 → 100644
View file @
d14dac18
/******************************************************************************************
* Chili DirectX Framework Version 16.07.20 *
* Mouse.h *
* Copyright 2016 PlanetChili <http://www.planetchili.net> *
* *
* This file is part of The Chili DirectX Framework. *
* *
* The Chili DirectX Framework is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* The Chili DirectX Framework is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with The Chili DirectX Framework. If not, see <http://www.gnu.org/licenses/>. *
******************************************************************************************/
#pragma once
#include <queue>
class
Mouse
{
friend
class
Window
;
public:
class
Event
{
public:
enum
class
Type
{
LPress
,
LRelease
,
RPress
,
RRelease
,
WheelUp
,
WheelDown
,
Move
,
Enter
,
Leave
,
Invalid
};
private:
Type
type
;
bool
leftIsPressed
;
bool
rightIsPressed
;
int
x
;
int
y
;
public:
Event
()
noexcept
:
type
(
Type
::
Invalid
),
leftIsPressed
(
false
),
rightIsPressed
(
false
),
x
(
0
),
y
(
0
)
{}
Event
(
Type
type
,
const
Mouse
&
parent
)
noexcept
:
type
(
type
),
leftIsPressed
(
parent
.
leftIsPressed
),
rightIsPressed
(
parent
.
rightIsPressed
),
x
(
parent
.
x
),
y
(
parent
.
y
)
{}
bool
IsValid
()
const
noexcept
{
return
type
!=
Type
::
Invalid
;
}
Type
GetType
()
const
noexcept
{
return
type
;
}
std
::
pair
<
int
,
int
>
GetPos
()
const
noexcept
{
return
{
x
,
y
};
}
int
GetPosX
()
const
noexcept
{
return
x
;
}
int
GetPosY
()
const
noexcept
{
return
y
;
}
bool
LeftIsPressed
()
const
noexcept
{
return
leftIsPressed
;
}
bool
RightIsPressed
()
const
noexcept
{
return
rightIsPressed
;
}
};
public:
Mouse
()
=
default
;
Mouse
(
const
Mouse
&
)
=
delete
;
Mouse
&
operator
=
(
const
Mouse
&
)
=
delete
;
std
::
pair
<
int
,
int
>
GetPos
()
const
noexcept
;
int
GetPosX
()
const
noexcept
;
int
GetPosY
()
const
noexcept
;
bool
IsInWindow
()
const
noexcept
;
bool
LeftIsPressed
()
const
noexcept
;
bool
RightIsPressed
()
const
noexcept
;
Mouse
::
Event
Read
()
noexcept
;
bool
IsEmpty
()
const
noexcept
{
return
buffer
.
empty
();
}
void
Flush
()
noexcept
;
private:
void
OnMouseMove
(
int
x
,
int
y
)
noexcept
;
void
OnMouseEnter
()
noexcept
;
void
OnMouseLeave
()
noexcept
;
void
OnLeftPressed
(
int
x
,
int
y
)
noexcept
;
void
OnLeftReleased
(
int
x
,
int
y
)
noexcept
;
void
OnRightPressed
(
int
x
,
int
y
)
noexcept
;
void
OnRightReleased
(
int
x
,
int
y
)
noexcept
;
void
OnWheelUp
(
int
x
,
int
y
)
noexcept
;
void
OnWheelDown
(
int
x
,
int
y
)
noexcept
;
void
OnWheelDelta
(
int
x
,
int
y
,
int
delta
)
noexcept
;
void
TrimBuffer
()
noexcept
;
private:
static
constexpr
unsigned
int
bufferSize
=
16u
;
int
x
;
int
y
;
bool
leftIsPressed
=
false
;
bool
rightIsPressed
=
false
;
bool
isInWindow
=
false
;
// 执行滚轮事件的次数,正数表示向上滚动,负数表示向下滚动
int
wheelDeltaCarry
=
0
;
std
::
queue
<
Event
>
buffer
;
};
\ No newline at end of file
StudyDx/StudyDx.vcxproj
View file @
d14dac18
...
...
@@ -139,6 +139,7 @@
<ItemGroup>
<ClCompile
Include=
"ChiliException.cpp"
/>
<ClCompile
Include=
"Keyboard.cpp"
/>
<ClCompile
Include=
"Mouse.cpp"
/>
<ClCompile
Include=
"Window.cpp"
/>
<ClCompile
Include=
"WindowsMessageMap.cpp"
/>
<ClCompile
Include=
"WinMain.cpp"
/>
...
...
@@ -147,6 +148,7 @@
<ClInclude
Include=
"ChiliException.h"
/>
<ClInclude
Include=
"ChiliWin.h"
/>
<ClInclude
Include=
"Keyboard.h"
/>
<ClInclude
Include=
"Mouse.h"
/>
<ClInclude
Include=
"resource.h"
/>
<ClInclude
Include=
"Window.h"
/>
<ClInclude
Include=
"WindowsMessageMap.h"
/>
...
...
StudyDx/WinMain.cpp
View file @
d14dac18
...
...
@@ -18,7 +18,7 @@
* along with The Chili Direct3D Engine. If not, see <http://www.gnu.org/licenses/>. *
******************************************************************************************/
#include "Window.h"
#include <sstream>
int
CALLBACK
WinMain
(
HINSTANCE
hInstance
,
...
...
@@ -38,9 +38,41 @@ int CALLBACK WinMain(
TranslateMessage
(
&
msg
);
DispatchMessage
(
&
msg
);
if
(
wnd
.
kbd
.
KeyIsPressed
(
VK_SPACE
)
||
wnd
.
kbd
.
KeyIsPressed
(
VK_MENU
))
// if (wnd.kbd.KeyIsPressed(VK_SPACE) || wnd.kbd.KeyIsPressed(VK_MENU))
// {
// MessageBox(nullptr, "Something happens!", "Space key was pressed", MB_OK | MB_ICONEXCLAMATION);
// }
while
(
!
wnd
.
mouse
.
IsEmpty
())
{
MessageBox
(
nullptr
,
"Something happens!"
,
"Space key was pressed"
,
MB_OK
|
MB_ICONEXCLAMATION
);
const
auto
e
=
wnd
.
mouse
.
Read
();
static
int
i
=
0
;
switch
(
e
.
GetType
())
{
case
Mouse
::
Event
::
Type
::
Move
:
{
std
::
ostringstream
oss
;
oss
<<
"Mouse Position: ("
<<
e
.
GetPosX
()
<<
","
<<
e
.
GetPosY
()
<<
"), "
<<
"Mouse Press Status: ("
<<
wnd
.
mouse
.
LeftIsPressed
()
<<
","
<<
wnd
.
mouse
.
RightIsPressed
()
<<
")"
;
wnd
.
SetTitle
(
oss
.
str
());
break
;
}
case
Mouse
::
Event
::
Type
::
WheelUp
:
{
i
++
;
std
::
ostringstream
oss
;
oss
<<
"Up: "
<<
i
;
wnd
.
SetTitle
(
oss
.
str
());
break
;
}
case
Mouse
::
Event
::
Type
::
WheelDown
:
{
i
--
;
std
::
ostringstream
oss
;
oss
<<
"Down: "
<<
i
;
wnd
.
SetTitle
(
oss
.
str
());
break
;
}
}
}
}
...
...
StudyDx/Window.cpp
View file @
d14dac18
...
...
@@ -85,6 +85,9 @@ HINSTANCE Window::WindowClass::GetInstance() noexcept
// Window Stuff
Window
::
Window
(
int
width
,
int
height
,
const
char
*
name
)
:
width
(
width
),
height
(
height
)
{
// calculate window size based on desired client region size
RECT
wr
;
...
...
@@ -92,10 +95,10 @@ Window::Window( int width,int height,const char* name )
wr
.
right
=
width
+
wr
.
left
;
wr
.
top
=
100
;
wr
.
bottom
=
height
+
wr
.
top
;
if
(
FAILED
(
AdjustWindowRect
(
&
wr
,
WS_CAPTION
|
WS_MINIMIZEBOX
|
WS_SYSMENU
,
FALSE
)
)
)
if
(
AdjustWindowRect
(
&
wr
,
WS_CAPTION
|
WS_MINIMIZEBOX
|
WS_SYSMENU
,
FALSE
)
==
0
)
{
throw
CHWND_LAST_EXCEPT
();
}
;
}
// create window & get hWnd
hWnd
=
CreateWindow
(
...
...
@@ -118,6 +121,14 @@ Window::~Window()
DestroyWindow
(
hWnd
);
}
void
Window
::
SetTitle
(
const
std
::
string
&
title
)
{
if
(
SetWindowText
(
hWnd
,
title
.
c_str
())
==
0
)
{
throw
CHWND_LAST_EXCEPT
();
}
}
LRESULT
CALLBACK
Window
::
HandleMsgSetup
(
HWND
hWnd
,
UINT
msg
,
WPARAM
wParam
,
LPARAM
lParam
)
noexcept
{
// use create parameter passed in from CreateWindow() to store window class pointer at WinAPI side
...
...
@@ -161,6 +172,11 @@ LRESULT Window::HandleMsg( HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam ) noex
PostQuitMessage
(
0
);
return
0
;
// 如果窗口失去焦点,立刻清空所有队列中的成员
case
WM_KILLFOCUS
:
kbd
.
ClearState
();
break
;
// 记录Key被按下
case
WM_KEYDOWN
:
// Bipset的第28,29,30位固定是0,30位代表前一次按键状态,1代表按下。
...
...
@@ -173,6 +189,7 @@ LRESULT Window::HandleMsg( HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam ) noex
}
break
;
// 记录SysKey被按下
case
WM_SYSKEYDOWN
:
// 同上
if
(
!
(
lParam
&
0x40000000
)
||
kbd
.
AutorepeatIsEnabled
())
// filter autorepeat
...
...
@@ -181,6 +198,8 @@ LRESULT Window::HandleMsg( HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam ) noex
}
break
;
// 记录SysKey被释放
case
WM_SYSKEYUP
:
// 记录Key释放
case
WM_KEYUP
:
kbd
.
OnKeyReleased
(
static_cast
<
unsigned
char
>
(
wParam
));
...
...
@@ -191,12 +210,86 @@ LRESULT Window::HandleMsg( HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam ) noex
kbd
.
OnChar
(
static_cast
<
unsigned
char
>
(
wParam
));
break
;
// 如果窗口失去焦点,立刻清空所有队列中的成员
case
WM_KILLFOCUS
:
kbd
.
ClearState
();
// 鼠标移动
case
WM_MOUSEMOVE
:
{
const
POINTS
pt
=
MAKEPOINTS
(
lParam
);
mouse
.
OnMouseMove
(
pt
.
x
,
pt
.
y
);
// in client region -> log move, and log enter + capture mouse (if not previously in window)
// 判断是否在窗口内
if
(
pt
.
x
>=
0
&&
pt
.
x
<=
width
&&
pt
.
y
>=
0
and
pt
.
y
<=
height
)
{
// 如果鼠标在窗口内,那么一定会记录鼠标的移动
mouse
.
OnMouseMove
(
pt
.
x
,
pt
.
y
);
// 判断之前的鼠标状态。如果之前不在窗口内,那么说明现在是从外面移动进入窗口内
if
(
!
mouse
.
IsInWindow
())
{
SetCapture
(
hWnd
);
mouse
.
OnMouseEnter
();
}
}
else
{
// 当鼠标移动到了窗口外,如果之前左键或者右键是按住的状态,那么被识别为拖拽
if
(
mouse
.
LeftIsPressed
()
||
mouse
.
RightIsPressed
())
{
// 拖拽过程中,依然会记录鼠标的移动
mouse
.
OnMouseMove
(
pt
.
x
,
pt
.
y
);
}
else
{
// 否则的话,释放对鼠标的捕获
ReleaseCapture
();
mouse
.
OnMouseLeave
();
}
}
break
;
}
// 点击左键
case
WM_LBUTTONDOWN
:
{
const
POINTS
pt
=
MAKEPOINTS
(
lParam
);
mouse
.
OnLeftPressed
(
pt
.
x
,
pt
.
y
);
break
;
}
// 点击右键
case
WM_RBUTTONDOWN
:
{
const
POINTS
pt
=
MAKEPOINTS
(
lParam
);
mouse
.
OnRightPressed
(
pt
.
x
,
pt
.
y
);
break
;
}
// 释放左键
case
WM_LBUTTONUP
:
{
const
POINTS
pt
=
MAKEPOINTS
(
lParam
);
mouse
.
OnLeftReleased
(
pt
.
x
,
pt
.
y
);
break
;
}
// 释放右键
{
case
WM_RBUTTONUP
:
const
POINTS
pt
=
MAKEPOINTS
(
lParam
);
mouse
.
OnRightReleased
(
pt
.
x
,
pt
.
y
);
break
;
}
// 鼠标滚轮
case
WM_MOUSEWHEEL
:
{
const
POINTS
pt
=
MAKEPOINTS
(
lParam
);
const
int
delta
=
GET_WHEEL_DELTA_WPARAM
(
wParam
);
mouse
.
OnWheelDelta
(
pt
.
x
,
pt
.
y
,
delta
);
break
;
}
}
return
DefWindowProc
(
hWnd
,
msg
,
wParam
,
lParam
);
}
...
...
StudyDx/Window.h
View file @
d14dac18
...
...
@@ -21,6 +21,7 @@
#include "ChiliWin.h"
#include "ChiliException.h"
#include "Keyboard.h"
#include "Mouse.h"
class
Window
...
...
@@ -59,12 +60,14 @@ public:
~
Window
();
Window
(
const
Window
&
)
=
delete
;
Window
&
operator
=
(
const
Window
&
)
=
delete
;
void
SetTitle
(
const
std
::
string
&
title
);
private:
static
LRESULT
CALLBACK
HandleMsgSetup
(
HWND
hWnd
,
UINT
msg
,
WPARAM
wParam
,
LPARAM
lParam
)
noexcept
;
static
LRESULT
CALLBACK
HandleMsgThunk
(
HWND
hWnd
,
UINT
msg
,
WPARAM
wParam
,
LPARAM
lParam
)
noexcept
;
LRESULT
HandleMsg
(
HWND
hWnd
,
UINT
msg
,
WPARAM
wParam
,
LPARAM
lParam
)
noexcept
;
public:
Keyboard
kbd
;
Mouse
mouse
;
private:
int
width
;
int
height
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment