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
ac85e129
Commit
ac85e129
authored
Dec 16, 2022
by
Administrator
Browse files
add keyboard event handle
parent
8ea2f717
Changes
6
Show whitespace changes
Inline
Side-by-side
StudyDx/Keyboard.cpp
0 → 100644
View file @
ac85e129
/******************************************************************************************
* Chili Direct3D Engine *
* Copyright 2018 PlanetChili <http://www.planetchili.net> *
* *
* This file is part of Chili Direct3D Engine. *
* *
* Chili Direct3D Engine 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 Direct3D Engine 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 Direct3D Engine. If not, see <http://www.gnu.org/licenses/>. *
******************************************************************************************/
#include "Keyboard.h"
bool
Keyboard
::
KeyIsPressed
(
unsigned
char
keycode
)
const
noexcept
{
return
keystates
[
keycode
];
}
Keyboard
::
Event
Keyboard
::
ReadKey
()
noexcept
{
if
(
keybuffer
.
size
()
>
0u
)
{
Keyboard
::
Event
e
=
keybuffer
.
front
();
keybuffer
.
pop
();
return
e
;
}
else
{
return
Keyboard
::
Event
();
}
}
bool
Keyboard
::
KeyIsEmpty
()
const
noexcept
{
return
keybuffer
.
empty
();
}
char
Keyboard
::
ReadChar
()
noexcept
{
if
(
charbuffer
.
size
()
>
0u
)
{
unsigned
char
charcode
=
charbuffer
.
front
();
charbuffer
.
pop
();
return
charcode
;
}
else
{
return
0
;
}
}
bool
Keyboard
::
CharIsEmpty
()
const
noexcept
{
return
charbuffer
.
empty
();
}
void
Keyboard
::
FlushKey
()
noexcept
{
keybuffer
=
std
::
queue
<
Event
>
();
}
void
Keyboard
::
FlushChar
()
noexcept
{
charbuffer
=
std
::
queue
<
char
>
();
}
void
Keyboard
::
Flush
()
noexcept
{
FlushKey
();
FlushChar
();
}
void
Keyboard
::
EnableAutorepeat
()
noexcept
{
autorepeatEnabled
=
true
;
}
void
Keyboard
::
DisableAutorepeat
()
noexcept
{
autorepeatEnabled
=
false
;
}
bool
Keyboard
::
AutorepeatIsEnabled
()
const
noexcept
{
return
autorepeatEnabled
;
}
void
Keyboard
::
OnKeyPressed
(
unsigned
char
keycode
)
noexcept
{
keystates
[
keycode
]
=
true
;
keybuffer
.
push
(
Keyboard
::
Event
(
Keyboard
::
Event
::
Type
::
Press
,
keycode
)
);
TrimBuffer
(
keybuffer
);
}
void
Keyboard
::
OnKeyReleased
(
unsigned
char
keycode
)
noexcept
{
keystates
[
keycode
]
=
false
;
keybuffer
.
push
(
Keyboard
::
Event
(
Keyboard
::
Event
::
Type
::
Release
,
keycode
)
);
TrimBuffer
(
keybuffer
);
}
void
Keyboard
::
OnChar
(
char
character
)
noexcept
{
charbuffer
.
push
(
character
);
TrimBuffer
(
charbuffer
);
}
void
Keyboard
::
ClearState
()
noexcept
{
keystates
.
reset
();
}
template
<
typename
T
>
void
Keyboard
::
TrimBuffer
(
std
::
queue
<
T
>&
buffer
)
noexcept
{
while
(
buffer
.
size
()
>
bufferSize
)
{
buffer
.
pop
();
}
}
StudyDx/Keyboard.h
0 → 100644
View file @
ac85e129
/******************************************************************************************
* Chili Direct3D Engine *
* Copyright 2018 PlanetChili <http://www.planetchili.net> *
* *
* This file is part of Chili Direct3D Engine. *
* *
* Chili Direct3D Engine 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 Direct3D Engine 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 Direct3D Engine. If not, see <http://www.gnu.org/licenses/>. *
******************************************************************************************/
#pragma once
#include <queue>
#include <bitset>
class
Keyboard
{
friend
class
Window
;
public:
class
Event
{
public:
enum
class
Type
{
Press
,
Release
,
Invalid
};
private:
Type
type
;
unsigned
char
code
;
public:
Event
()
:
type
(
Type
::
Invalid
),
code
(
0u
)
{}
Event
(
Type
type
,
unsigned
char
code
)
noexcept
:
type
(
type
),
code
(
code
)
{}
bool
IsPress
()
const
noexcept
{
return
type
==
Type
::
Press
;
}
bool
IsRelease
()
const
noexcept
{
return
type
==
Type
::
Release
;
}
bool
IsValid
()
const
noexcept
{
return
type
!=
Type
::
Invalid
;
}
unsigned
char
GetCode
()
const
noexcept
{
return
code
;
}
};
public:
Keyboard
()
=
default
;
// 单例设计
Keyboard
(
const
Keyboard
&
)
=
delete
;
// 单例设计
Keyboard
&
operator
=
(
const
Keyboard
&
)
=
delete
;
// key event stuff
// 根据bitset keystates中指定Key的状态
bool
KeyIsPressed
(
unsigned
char
keycode
)
const
noexcept
;
// 从keyBuffer队列中找到最前面的Event,取出并移出队列
Event
ReadKey
()
noexcept
;
// 检查keyBuffer队列是否为空
bool
KeyIsEmpty
()
const
noexcept
;
// 重置keyBuffer队列
void
FlushKey
()
noexcept
;
// char event stuff
// 从charBuff队列中找到最前面的Event,取出并移出队列
char
ReadChar
()
noexcept
;
// 检查charBuffer队列是否为空
bool
CharIsEmpty
()
const
noexcept
;
// 重置charBuffer队列
void
FlushChar
()
noexcept
;
// 重置keyBuffer和charBuffer队列
void
Flush
()
noexcept
;
// autorepeat control
void
EnableAutorepeat
()
noexcept
;
void
DisableAutorepeat
()
noexcept
;
bool
AutorepeatIsEnabled
()
const
noexcept
;
private:
void
OnKeyPressed
(
unsigned
char
keycode
)
noexcept
;
void
OnKeyReleased
(
unsigned
char
keycode
)
noexcept
;
void
OnChar
(
char
character
)
noexcept
;
void
ClearState
()
noexcept
;
template
<
typename
T
>
static
void
TrimBuffer
(
std
::
queue
<
T
>&
buffer
)
noexcept
;
private:
// Key的数量,Unsigned 256足够对应所有的Key
static
constexpr
unsigned
int
nKeys
=
256u
;
// 队列长度
static
constexpr
unsigned
int
bufferSize
=
16u
;
// Todo
bool
autorepeatEnabled
=
false
;
// 用于存放每个Key的状态,每个bit的值对应一个Key的状态
std
::
bitset
<
nKeys
>
keystates
;
// 用于存放Key事件的队列
std
::
queue
<
Event
>
keybuffer
;
// 用于存放Char的队列
std
::
queue
<
char
>
charbuffer
;
};
\ No newline at end of file
StudyDx/StudyDx.vcxproj
View file @
ac85e129
...
...
@@ -138,6 +138,7 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile
Include=
"ChiliException.cpp"
/>
<ClCompile
Include=
"Keyboard.cpp"
/>
<ClCompile
Include=
"Window.cpp"
/>
<ClCompile
Include=
"WindowsMessageMap.cpp"
/>
<ClCompile
Include=
"WinMain.cpp"
/>
...
...
@@ -145,6 +146,7 @@
<ItemGroup>
<ClInclude
Include=
"ChiliException.h"
/>
<ClInclude
Include=
"ChiliWin.h"
/>
<ClInclude
Include=
"Keyboard.h"
/>
<ClInclude
Include=
"resource.h"
/>
<ClInclude
Include=
"Window.h"
/>
<ClInclude
Include=
"WindowsMessageMap.h"
/>
...
...
StudyDx/WinMain.cpp
View file @
ac85e129
...
...
@@ -37,6 +37,11 @@ int CALLBACK WinMain(
// TranslateMessage will post auxilliary WM_CHAR messages from key msgs
TranslateMessage
(
&
msg
);
DispatchMessage
(
&
msg
);
if
(
wnd
.
kbd
.
KeyIsPressed
(
VK_SPACE
)
||
wnd
.
kbd
.
KeyIsPressed
(
VK_MENU
))
{
MessageBox
(
nullptr
,
"Something happens!"
,
"Space key was pressed"
,
MB_OK
|
MB_ICONEXCLAMATION
);
}
}
// check if GetMessage call itself borked
...
...
StudyDx/Window.cpp
View file @
ac85e129
...
...
@@ -160,6 +160,41 @@ LRESULT Window::HandleMsg( HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam ) noex
case
WM_CLOSE
:
PostQuitMessage
(
0
);
return
0
;
// 记录Key被按下
case
WM_KEYDOWN
:
// Bipset的第28,29,30位固定是0,30位代表前一次按键状态,1代表按下。
// 因此28-31的16进制值如果是4的话,表示前一次是按下的状态,这次是持续按键
// 如果Key被持续按下,第一个条件不成立,不执行操作
// 在以上的基础上,提供Autorepeat的选项。如果启用Autorepeat,那么即使持续按键,也执行操作
if
(
!
(
lParam
&
0x40000000
)
||
kbd
.
AutorepeatIsEnabled
())
// filter autorepeat
{
kbd
.
OnKeyPressed
(
static_cast
<
unsigned
char
>
(
wParam
));
}
break
;
case
WM_SYSKEYDOWN
:
// 同上
if
(
!
(
lParam
&
0x40000000
)
||
kbd
.
AutorepeatIsEnabled
())
// filter autorepeat
{
kbd
.
OnKeyPressed
(
static_cast
<
unsigned
char
>
(
wParam
));
}
break
;
// 记录Key释放
case
WM_KEYUP
:
kbd
.
OnKeyReleased
(
static_cast
<
unsigned
char
>
(
wParam
));
break
;
// 记录文字输入
case
WM_CHAR
:
kbd
.
OnChar
(
static_cast
<
unsigned
char
>
(
wParam
));
break
;
// 如果窗口失去焦点,立刻清空所有队列中的成员
case
WM_KILLFOCUS
:
kbd
.
ClearState
();
break
;
}
return
DefWindowProc
(
hWnd
,
msg
,
wParam
,
lParam
);
...
...
StudyDx/Window.h
View file @
ac85e129
...
...
@@ -20,6 +20,7 @@
#pragma once
#include "ChiliWin.h"
#include "ChiliException.h"
#include "Keyboard.h"
class
Window
...
...
@@ -62,6 +63,8 @@ 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
;
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